]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
btrfs: raid56: extract scrub read bio list assembly code into a helper
authorQu Wenruo <wqu@suse.com>
Tue, 1 Nov 2022 11:16:10 +0000 (19:16 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 5 Dec 2022 17:00:49 +0000 (18:00 +0100)
Just like what we did for write/recovery, also extract the read bio
assembly code into a helper for scrub.

The difference between the three are:

- rmw_assemble_read_bios() only submit reads for missing sectors
  Thus it will skip cached sectors, but will also read sectors which
  is not covered by any full stripe. (For cache usage)

- recover_assemble_read_bios() reads every sector which has not failed

- scrub_assemble_read_bios() has extra check for vertical stripes
  It's mostly the same as rmw_assemble_read_bios(), but will skip
  sectors which is not covered by a vertical stripe.

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

index ffedbfde95e0d797276a30e13934a54449dd8791..fcac70ff5a7864ca8a2ce9d7151e01379629cef5 100644 (file)
@@ -2707,21 +2707,15 @@ static void raid56_parity_scrub_end_io_work(struct work_struct *work)
        validate_rbio_for_parity_scrub(rbio);
 }
 
-static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
+static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio,
+                                   struct bio_list *bio_list)
 {
-       int bios_to_read = 0;
-       struct bio_list bio_list;
-       int ret;
-       int total_sector_nr;
        struct bio *bio;
+       int total_sector_nr;
+       int ret = 0;
 
-       bio_list_init(&bio_list);
-
-       ret = alloc_rbio_essential_pages(rbio);
-       if (ret)
-               goto cleanup;
+       ASSERT(bio_list_size(bio_list) == 0);
 
-       atomic_set(&rbio->error, 0);
        /* Build a list of bios to read all the missing parts. */
        for (total_sector_nr = 0; total_sector_nr < rbio->nr_sectors;
             total_sector_nr++) {
@@ -2750,11 +2744,35 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
                if (sector->uptodate)
                        continue;
 
-               ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
+               ret = rbio_add_io_sector(rbio, bio_list, sector, stripe,
                                         sectornr, REQ_OP_READ);
                if (ret)
-                       goto cleanup;
+                       goto error;
        }
+       return 0;
+error:
+       while ((bio = bio_list_pop(bio_list)))
+               bio_put(bio);
+       return ret;
+}
+
+static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
+{
+       int bios_to_read = 0;
+       struct bio_list bio_list;
+       int ret;
+       struct bio *bio;
+
+       bio_list_init(&bio_list);
+
+       ret = alloc_rbio_essential_pages(rbio);
+       if (ret)
+               goto cleanup;
+
+       atomic_set(&rbio->error, 0);
+       ret = scrub_assemble_read_bios(rbio, &bio_list);
+       if (ret < 0)
+               goto cleanup;
 
        bios_to_read = bio_list_size(&bio_list);
        if (!bios_to_read) {