Skip to content

Commit 9042dc0

Browse files
adam900710kdave
authored andcommitted
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>
1 parent 54df8b8 commit 9042dc0

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

fs/btrfs/raid56.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,76 @@ enum btrfs_rbio_ops {
2424
BTRFS_RBIO_PARITY_SCRUB,
2525
};
2626

27+
/*
28+
* Overview of btrfs_raid_bio.
29+
*
30+
* One btrfs_raid_bio represents a full stripe of RAID56, including both data
31+
* and P/Q stripes. For now, each data and P/Q stripe is of a fixed length (64K).
32+
*
33+
* One btrfs_raid_bio can have one or more bios from higher layer, covering
34+
* part or all of the data stripes.
35+
*
36+
* [PAGES FROM HIGHER LAYER BIOS]
37+
* Higher layer bios are in the btrfs_raid_bio::bio_list.
38+
*
39+
* Pages from the bio_list are represented like the following:
40+
*
41+
* bio_list: |<- Bio 1 ->| |<- Bio 2 ->| ...
42+
* bio_paddrs: [0] [1] [2] [3] [4] [5] ...
43+
*
44+
* If there is a bio covering a sector (one btrfs fs block), the corresponding
45+
* pointer in btrfs_raid_bio::bio_paddrs[] will point to the physical address
46+
* (with the offset inside the page) of the corresponding bio.
47+
*
48+
* If there is no bio covering a sector, then btrfs_raid_bio::bio_paddrs[i] will
49+
* be INVALID_PADDR.
50+
*
51+
* The length of each entry in bio_paddrs[] is sectorsize.
52+
*
53+
* [PAGES FOR INTERNAL USAGES]
54+
* Pages not covered by any bio or belonging to P/Q stripes are stored in
55+
* btrfs_raid_bio::stripe_pages[] and stripe_paddrs[], like the following:
56+
*
57+
* stripe_pages: |<- Page 0 ->|<- Page 1 ->| ...
58+
* stripe_paddrs: [0] [1] [2] [3] [4] ...
59+
*
60+
* stripe_pages[] array stores all the pages covering the full stripe, including
61+
* data and P/Q pages.
62+
* stripe_pages[0] is the first page of the first data stripe.
63+
* stripe_pages[BTRFS_STRIPE_LEN / PAGE_SIZE] is the first page of the second
64+
* data stripe.
65+
*
66+
* Some pointers inside stripe_pages[] can be NULL, e.g. for a full stripe write
67+
* (the bio covers all data stripes) there is no need to allocate pages for
68+
* data stripes (can grab from bio_paddrs[]).
69+
*
70+
* If the corresponding page of stripe_paddrs[i] is not allocated, the value of
71+
* stripe_paddrs[i] will be INVALID_PADDR.
72+
*
73+
* The length of each entry in stripe_paddrs[] is sectorsize.
74+
*
75+
* [LOCATING A SECTOR]
76+
* To locate a sector for IO, we need the following info:
77+
*
78+
* - stripe_nr
79+
* Starts from 0 (representing the first data stripe), ends at
80+
* @nr_data (RAID5, P stripe) or @nr_data + 1 (RAID6, Q stripe).
81+
*
82+
* - sector_nr
83+
* Starts from 0 (representing the first sector of the stripe), ends
84+
* at BTRFS_STRIPE_LEN / sectorsize - 1.
85+
*
86+
* All existing bitmaps are based on sector numbers.
87+
*
88+
* - from which array
89+
* Whether grabbing from stripe_paddrs[] (aka, internal pages) or from the
90+
* bio_paddrs[] (aka, from the higher layer bios).
91+
*
92+
* For IO, a physical address is returned, so that we can extract the page and
93+
* the offset inside the page for IO.
94+
* A special value INVALID_PADDR represents when the physical address is invalid,
95+
* normally meaning there is no page allocated for the specified sector.
96+
*/
2797
struct btrfs_raid_bio {
2898
struct btrfs_io_context *bioc;
2999

0 commit comments

Comments
 (0)