btrfs: raid56: make finish_rmw() subpage compatible
authorQu Wenruo <wqu@suse.com>
Fri, 1 Apr 2022 11:23:24 +0000 (19:23 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 16 May 2022 15:03:15 +0000 (17:03 +0200)
With this function converted to subpage compatible sector interfaces,
the following helper functions can be removed:

- rbio_stripe_page()
- rbio_pstripe_page()
- rbio_qstripe_page()
- page_in_rbio()

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/raid56.c

index 0b446bd..262cabe 100644 (file)
@@ -685,39 +685,25 @@ static struct sector_ptr *rbio_stripe_sector(const struct btrfs_raid_bio *rbio,
                                                              sector_nr)];
 }
 
-static int rbio_stripe_page_index(struct btrfs_raid_bio *rbio, int stripe,
-                                 int index)
+/* Grab a sector inside P stripe */
+static struct sector_ptr *rbio_pstripe_sector(const struct btrfs_raid_bio *rbio,
+                                             unsigned int sector_nr)
 {
-       return stripe * rbio->stripe_npages + index;
-}
-
-/*
- * these are just the pages from the rbio array, not from anything
- * the FS sent down to us
- */
-static struct page *rbio_stripe_page(struct btrfs_raid_bio *rbio, int stripe,
-                                    int index)
-{
-       return rbio->stripe_pages[rbio_stripe_page_index(rbio, stripe, index)];
+       return rbio_stripe_sector(rbio, rbio->nr_data, sector_nr);
 }
 
-/*
- * helper to index into the pstripe
- */
-static struct page *rbio_pstripe_page(struct btrfs_raid_bio *rbio, int index)
+/* Grab a sector inside Q stripe, return NULL if not RAID6 */
+static struct sector_ptr *rbio_qstripe_sector(const struct btrfs_raid_bio *rbio,
+                                             unsigned int sector_nr)
 {
-       return rbio_stripe_page(rbio, rbio->nr_data, index);
+       if (rbio->nr_data + 1 == rbio->real_stripes)
+               return NULL;
+       return rbio_stripe_sector(rbio, rbio->nr_data + 1, sector_nr);
 }
 
-/*
- * helper to index into the qstripe, returns null
- * if there is no qstripe
- */
-static struct page *rbio_qstripe_page(struct btrfs_raid_bio *rbio, int index)
+static int rbio_stripe_page_index(struct btrfs_raid_bio *rbio, int stripe, int index)
 {
-       if (rbio->nr_data + 1 == rbio->real_stripes)
-               return NULL;
-       return rbio_stripe_page(rbio, rbio->nr_data + 1, index);
+       return stripe * rbio->stripe_npages + index;
 }
 
 /*
@@ -1036,40 +1022,6 @@ static struct sector_ptr *sector_in_rbio(struct btrfs_raid_bio *rbio,
 }
 
 /*
- * the read/modify/write code wants to use the original bio for
- * any pages it included, and then use the rbio for everything
- * else.  This function decides if a given index (stripe number)
- * and page number in that stripe fall inside the original bio
- * or the rbio.
- *
- * if you set bio_list_only, you'll get a NULL back for any ranges
- * that are outside the bio_list
- *
- * This doesn't take any refs on anything, you get a bare page pointer
- * and the caller must bump refs as required.
- *
- * You must call index_rbio_pages once before you can trust
- * the answers from this function.
- */
-static struct page *page_in_rbio(struct btrfs_raid_bio *rbio,
-                                int index, int pagenr, int bio_list_only)
-{
-       int chunk_page;
-       struct page *p = NULL;
-
-       chunk_page = index * (rbio->stripe_len >> PAGE_SHIFT) + pagenr;
-
-       spin_lock_irq(&rbio->bio_list_lock);
-       p = rbio->bio_pages[chunk_page];
-       spin_unlock_irq(&rbio->bio_list_lock);
-
-       if (p || bio_list_only)
-               return p;
-
-       return rbio->stripe_pages[chunk_page];
-}
-
-/*
  * allocation and initial setup for the btrfs_raid_bio.  Not
  * this does not allocate any pages for rbio->pages.
  */
@@ -1336,6 +1288,7 @@ static void index_rbio_pages(struct btrfs_raid_bio *rbio)
 static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
 {
        struct btrfs_io_context *bioc = rbio->bioc;
+       const u32 sectorsize = bioc->fs_info->sectorsize;
        void **pointers = rbio->finish_pointers;
        int nr_data = rbio->nr_data;
        int stripe;
@@ -1384,34 +1337,36 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
                clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
 
        for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) {
-               struct page *p;
-               /* first collect one page from each data stripe */
+               struct sector_ptr *sector;
+
+               /* First collect one sector from each data stripe */
                for (stripe = 0; stripe < nr_data; stripe++) {
-                       p = page_in_rbio(rbio, stripe, sectornr, 0);
-                       pointers[stripe] = kmap_local_page(p);
+                       sector = sector_in_rbio(rbio, stripe, sectornr, 0);
+                       pointers[stripe] = kmap_local_page(sector->page) +
+                                          sector->pgoff;
                }
 
-               /* then add the parity stripe */
-               p = rbio_pstripe_page(rbio, sectornr);
-               SetPageUptodate(p);
-               pointers[stripe++] = kmap_local_page(p);
+               /* Then add the parity stripe */
+               sector = rbio_pstripe_sector(rbio, sectornr);
+               sector->uptodate = 1;
+               pointers[stripe++] = kmap_local_page(sector->page) + sector->pgoff;
 
                if (has_qstripe) {
-
                        /*
-                        * raid6, add the qstripe and call the
-                        * library function to fill in our p/q
+                        * RAID6, add the qstripe and call the library function
+                        * to fill in our p/q
                         */
-                       p = rbio_qstripe_page(rbio, sectornr);
-                       SetPageUptodate(p);
-                       pointers[stripe++] = kmap_local_page(p);
+                       sector = rbio_qstripe_sector(rbio, sectornr);
+                       sector->uptodate = 1;
+                       pointers[stripe++] = kmap_local_page(sector->page) +
+                                            sector->pgoff;
 
-                       raid6_call.gen_syndrome(rbio->real_stripes, PAGE_SIZE,
+                       raid6_call.gen_syndrome(rbio->real_stripes, sectorsize,
                                                pointers);
                } else {
                        /* raid5 */
-                       copy_page(pointers[nr_data], pointers[0]);
-                       run_xor(pointers + 1, nr_data - 1, PAGE_SIZE);
+                       memcpy(pointers[nr_data], pointers[0], sectorsize);
+                       run_xor(pointers + 1, nr_data - 1, sectorsize);
                }
                for (stripe = stripe - 1; stripe >= 0; stripe--)
                        kunmap_local(pointers[stripe]);