mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
btrfs: raid56: add an overview for the btrfs_raid_bio structure
The structure needs to track both the pages from higher layer bio and internal pages, thus it can be a little complex to grasp. Add an overview of the structure, especially how we track different pages from higher layer bios and internal ones, to save some time for future developers. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
@@ -24,6 +24,76 @@ enum btrfs_rbio_ops {
|
||||
BTRFS_RBIO_PARITY_SCRUB,
|
||||
};
|
||||
|
||||
/*
|
||||
* Overview of btrfs_raid_bio.
|
||||
*
|
||||
* One btrfs_raid_bio represents a full stripe of RAID56, including both data
|
||||
* and P/Q stripes. For now, each data and P/Q stripe is of a fixed length (64K).
|
||||
*
|
||||
* One btrfs_raid_bio can have one or more bios from higher layer, covering
|
||||
* part or all of the data stripes.
|
||||
*
|
||||
* [PAGES FROM HIGHER LAYER BIOS]
|
||||
* Higher layer bios are in the btrfs_raid_bio::bio_list.
|
||||
*
|
||||
* Pages from the bio_list are represented like the following:
|
||||
*
|
||||
* bio_list: |<- Bio 1 ->| |<- Bio 2 ->| ...
|
||||
* bio_paddrs: [0] [1] [2] [3] [4] [5] ...
|
||||
*
|
||||
* If there is a bio covering a sector (one btrfs fs block), the corresponding
|
||||
* pointer in btrfs_raid_bio::bio_paddrs[] will point to the physical address
|
||||
* (with the offset inside the page) of the corresponding bio.
|
||||
*
|
||||
* If there is no bio covering a sector, then btrfs_raid_bio::bio_paddrs[i] will
|
||||
* be INVALID_PADDR.
|
||||
*
|
||||
* The length of each entry in bio_paddrs[] is sectorsize.
|
||||
*
|
||||
* [PAGES FOR INTERNAL USAGES]
|
||||
* Pages not covered by any bio or belonging to P/Q stripes are stored in
|
||||
* btrfs_raid_bio::stripe_pages[] and stripe_paddrs[], like the following:
|
||||
*
|
||||
* stripe_pages: |<- Page 0 ->|<- Page 1 ->| ...
|
||||
* stripe_paddrs: [0] [1] [2] [3] [4] ...
|
||||
*
|
||||
* stripe_pages[] array stores all the pages covering the full stripe, including
|
||||
* data and P/Q pages.
|
||||
* stripe_pages[0] is the first page of the first data stripe.
|
||||
* stripe_pages[BTRFS_STRIPE_LEN / PAGE_SIZE] is the first page of the second
|
||||
* data stripe.
|
||||
*
|
||||
* Some pointers inside stripe_pages[] can be NULL, e.g. for a full stripe write
|
||||
* (the bio covers all data stripes) there is no need to allocate pages for
|
||||
* data stripes (can grab from bio_paddrs[]).
|
||||
*
|
||||
* If the corresponding page of stripe_paddrs[i] is not allocated, the value of
|
||||
* stripe_paddrs[i] will be INVALID_PADDR.
|
||||
*
|
||||
* The length of each entry in stripe_paddrs[] is sectorsize.
|
||||
*
|
||||
* [LOCATING A SECTOR]
|
||||
* To locate a sector for IO, we need the following info:
|
||||
*
|
||||
* - stripe_nr
|
||||
* Starts from 0 (representing the first data stripe), ends at
|
||||
* @nr_data (RAID5, P stripe) or @nr_data + 1 (RAID6, Q stripe).
|
||||
*
|
||||
* - sector_nr
|
||||
* Starts from 0 (representing the first sector of the stripe), ends
|
||||
* at BTRFS_STRIPE_LEN / sectorsize - 1.
|
||||
*
|
||||
* All existing bitmaps are based on sector numbers.
|
||||
*
|
||||
* - from which array
|
||||
* Whether grabbing from stripe_paddrs[] (aka, internal pages) or from the
|
||||
* bio_paddrs[] (aka, from the higher layer bios).
|
||||
*
|
||||
* For IO, a physical address is returned, so that we can extract the page and
|
||||
* the offset inside the page for IO.
|
||||
* A special value INVALID_PADDR represents when the physical address is invalid,
|
||||
* normally meaning there is no page allocated for the specified sector.
|
||||
*/
|
||||
struct btrfs_raid_bio {
|
||||
struct btrfs_io_context *bioc;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user