162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2012 Fusion-io  All rights reserved.
462306a36Sopenharmony_ci * Copyright (C) 2012 Intel Corp. All rights reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef BTRFS_RAID56_H
862306a36Sopenharmony_ci#define BTRFS_RAID56_H
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/workqueue.h>
1162306a36Sopenharmony_ci#include "volumes.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cienum btrfs_rbio_ops {
1462306a36Sopenharmony_ci	BTRFS_RBIO_WRITE,
1562306a36Sopenharmony_ci	BTRFS_RBIO_READ_REBUILD,
1662306a36Sopenharmony_ci	BTRFS_RBIO_PARITY_SCRUB,
1762306a36Sopenharmony_ci};
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistruct btrfs_raid_bio {
2062306a36Sopenharmony_ci	struct btrfs_io_context *bioc;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	/*
2362306a36Sopenharmony_ci	 * While we're doing RMW on a stripe we put it into a hash table so we
2462306a36Sopenharmony_ci	 * can lock the stripe and merge more rbios into it.
2562306a36Sopenharmony_ci	 */
2662306a36Sopenharmony_ci	struct list_head hash_list;
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	/* LRU list for the stripe cache */
2962306a36Sopenharmony_ci	struct list_head stripe_cache;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	/* For scheduling work in the helper threads */
3262306a36Sopenharmony_ci	struct work_struct work;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	/*
3562306a36Sopenharmony_ci	 * bio_list and bio_list_lock are used to add more bios into the stripe
3662306a36Sopenharmony_ci	 * in hopes of avoiding the full RMW
3762306a36Sopenharmony_ci	 */
3862306a36Sopenharmony_ci	struct bio_list bio_list;
3962306a36Sopenharmony_ci	spinlock_t bio_list_lock;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	/*
4262306a36Sopenharmony_ci	 * Also protected by the bio_list_lock, the plug list is used by the
4362306a36Sopenharmony_ci	 * plugging code to collect partial bios while plugged.  The stripe
4462306a36Sopenharmony_ci	 * locking code also uses it to hand off the stripe lock to the next
4562306a36Sopenharmony_ci	 * pending IO.
4662306a36Sopenharmony_ci	 */
4762306a36Sopenharmony_ci	struct list_head plug_list;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	/* Flags that tell us if it is safe to merge with this bio. */
5062306a36Sopenharmony_ci	unsigned long flags;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	/*
5362306a36Sopenharmony_ci	 * Set if we're doing a parity rebuild for a read from higher up, which
5462306a36Sopenharmony_ci	 * is handled differently from a parity rebuild as part of RMW.
5562306a36Sopenharmony_ci	 */
5662306a36Sopenharmony_ci	enum btrfs_rbio_ops operation;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	/* How many pages there are for the full stripe including P/Q */
5962306a36Sopenharmony_ci	u16 nr_pages;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	/* How many sectors there are for the full stripe including P/Q */
6262306a36Sopenharmony_ci	u16 nr_sectors;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	/* Number of data stripes (no p/q) */
6562306a36Sopenharmony_ci	u8 nr_data;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	/* Number of all stripes (including P/Q) */
6862306a36Sopenharmony_ci	u8 real_stripes;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	/* How many pages there are for each stripe */
7162306a36Sopenharmony_ci	u8 stripe_npages;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	/* How many sectors there are for each stripe */
7462306a36Sopenharmony_ci	u8 stripe_nsectors;
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	/* Stripe number that we're scrubbing  */
7762306a36Sopenharmony_ci	u8 scrubp;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	/*
8062306a36Sopenharmony_ci	 * Size of all the bios in the bio_list.  This helps us decide if the
8162306a36Sopenharmony_ci	 * rbio maps to a full stripe or not.
8262306a36Sopenharmony_ci	 */
8362306a36Sopenharmony_ci	int bio_list_bytes;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	refcount_t refs;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	atomic_t stripes_pending;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	wait_queue_head_t io_wait;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	/* Bitmap to record which horizontal stripe has data */
9262306a36Sopenharmony_ci	unsigned long dbitmap;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	/* Allocated with stripe_nsectors-many bits for finish_*() calls */
9562306a36Sopenharmony_ci	unsigned long finish_pbitmap;
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	/*
9862306a36Sopenharmony_ci	 * These are two arrays of pointers.  We allocate the rbio big enough
9962306a36Sopenharmony_ci	 * to hold them both and setup their locations when the rbio is
10062306a36Sopenharmony_ci	 * allocated.
10162306a36Sopenharmony_ci	 */
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	/*
10462306a36Sopenharmony_ci	 * Pointers to pages that we allocated for reading/writing stripes
10562306a36Sopenharmony_ci	 * directly from the disk (including P/Q).
10662306a36Sopenharmony_ci	 */
10762306a36Sopenharmony_ci	struct page **stripe_pages;
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	/* Pointers to the sectors in the bio_list, for faster lookup */
11062306a36Sopenharmony_ci	struct sector_ptr *bio_sectors;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	/*
11362306a36Sopenharmony_ci	 * For subpage support, we need to map each sector to above
11462306a36Sopenharmony_ci	 * stripe_pages.
11562306a36Sopenharmony_ci	 */
11662306a36Sopenharmony_ci	struct sector_ptr *stripe_sectors;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	/* Allocated with real_stripes-many pointers for finish_*() calls */
11962306a36Sopenharmony_ci	void **finish_pointers;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	/*
12262306a36Sopenharmony_ci	 * The bitmap recording where IO errors happened.
12362306a36Sopenharmony_ci	 * Each bit is corresponding to one sector in either bio_sectors[] or
12462306a36Sopenharmony_ci	 * stripe_sectors[] array.
12562306a36Sopenharmony_ci	 *
12662306a36Sopenharmony_ci	 * The reason we don't use another bit in sector_ptr is, we have two
12762306a36Sopenharmony_ci	 * arrays of sectors, and a lot of IO can use sectors in both arrays.
12862306a36Sopenharmony_ci	 * Thus making it much harder to iterate.
12962306a36Sopenharmony_ci	 */
13062306a36Sopenharmony_ci	unsigned long *error_bitmap;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	/*
13362306a36Sopenharmony_ci	 * Checksum buffer if the rbio is for data.  The buffer should cover
13462306a36Sopenharmony_ci	 * all data sectors (excluding P/Q sectors).
13562306a36Sopenharmony_ci	 */
13662306a36Sopenharmony_ci	u8 *csum_buf;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	/*
13962306a36Sopenharmony_ci	 * Each bit represents if the corresponding sector has data csum found.
14062306a36Sopenharmony_ci	 * Should only cover data sectors (excluding P/Q sectors).
14162306a36Sopenharmony_ci	 */
14262306a36Sopenharmony_ci	unsigned long *csum_bitmap;
14362306a36Sopenharmony_ci};
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/*
14662306a36Sopenharmony_ci * For trace event usage only. Records useful debug info for each bio submitted
14762306a36Sopenharmony_ci * by RAID56 to each physical device.
14862306a36Sopenharmony_ci *
14962306a36Sopenharmony_ci * No matter signed or not, (-1) is always the one indicating we can not grab
15062306a36Sopenharmony_ci * the proper stripe number.
15162306a36Sopenharmony_ci */
15262306a36Sopenharmony_cistruct raid56_bio_trace_info {
15362306a36Sopenharmony_ci	u64 devid;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	/* The offset inside the stripe. (<= STRIPE_LEN) */
15662306a36Sopenharmony_ci	u32 offset;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	/*
15962306a36Sopenharmony_ci	 * Stripe number.
16062306a36Sopenharmony_ci	 * 0 is the first data stripe, and nr_data for P stripe,
16162306a36Sopenharmony_ci	 * nr_data + 1 for Q stripe.
16262306a36Sopenharmony_ci	 * >= real_stripes for
16362306a36Sopenharmony_ci	 */
16462306a36Sopenharmony_ci	u8 stripe_nr;
16562306a36Sopenharmony_ci};
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic inline int nr_data_stripes(const struct map_lookup *map)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	return map->num_stripes - btrfs_nr_parity_stripes(map->type);
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cistatic inline int nr_bioc_data_stripes(const struct btrfs_io_context *bioc)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	return bioc->num_stripes - btrfs_nr_parity_stripes(bioc->map_type);
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci#define RAID5_P_STRIPE ((u64)-2)
17862306a36Sopenharmony_ci#define RAID6_Q_STRIPE ((u64)-1)
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci#define is_parity_stripe(x) (((x) == RAID5_P_STRIPE) ||		\
18162306a36Sopenharmony_ci			     ((x) == RAID6_Q_STRIPE))
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistruct btrfs_device;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_civoid raid56_parity_recover(struct bio *bio, struct btrfs_io_context *bioc,
18662306a36Sopenharmony_ci			   int mirror_num);
18762306a36Sopenharmony_civoid raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc);
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_cistruct btrfs_raid_bio *raid56_parity_alloc_scrub_rbio(struct bio *bio,
19062306a36Sopenharmony_ci				struct btrfs_io_context *bioc,
19162306a36Sopenharmony_ci				struct btrfs_device *scrub_dev,
19262306a36Sopenharmony_ci				unsigned long *dbitmap, int stripe_nsectors);
19362306a36Sopenharmony_civoid raid56_parity_submit_scrub_rbio(struct btrfs_raid_bio *rbio);
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_civoid raid56_parity_cache_data_pages(struct btrfs_raid_bio *rbio,
19662306a36Sopenharmony_ci				    struct page **data_pages, u64 data_logical);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ciint btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info);
19962306a36Sopenharmony_civoid btrfs_free_stripe_hash_table(struct btrfs_fs_info *info);
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci#endif
202