]> git.baikalelectronics.ru Git - kernel.git/commitdiff
btrfs: raid56: avoid double for loop inside raid56_parity_scrub_stripe()
authorQu Wenruo <wqu@suse.com>
Wed, 8 Jun 2022 00:34:36 +0000 (08:34 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 25 Jul 2022 15:45:35 +0000 (17:45 +0200)
Originally it's iterating all the sectors which has dbitmap sector for
the vertical stripe.

It can be easily converted to sector bytenr iteration with an test_bit()
call.

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 7ddcac96e844dfac5e9cec29e2932a0626b723c7..f002334d244a77b56739df1477894e3a0a8fbf2e 100644 (file)
@@ -2661,8 +2661,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
        int bios_to_read = 0;
        struct bio_list bio_list;
        int ret;
-       int sectornr;
-       int stripe;
+       int total_sector_nr;
        struct bio *bio;
 
        bio_list_init(&bio_list);
@@ -2672,37 +2671,38 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
                goto cleanup;
 
        atomic_set(&rbio->error, 0);
-       /*
-        * build a list of bios to read all the missing parts of this
-        * stripe
-        */
-       for (stripe = 0; stripe < rbio->real_stripes; stripe++) {
-               for_each_set_bit(sectornr, &rbio->dbitmap, rbio->stripe_nsectors) {
-                       struct sector_ptr *sector;
-                       /*
-                        * We want to find all the sectors missing from the
-                        * rbio and read them from the disk.  If * sector_in_rbio()
-                        * finds a sector in the bio list we don't need to read
-                        * it off the stripe.
-                        */
-                       sector = sector_in_rbio(rbio, stripe, sectornr, 1);
-                       if (sector)
-                               continue;
+       /* 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++) {
+               int sectornr = total_sector_nr % rbio->stripe_nsectors;
+               int stripe = total_sector_nr / rbio->stripe_nsectors;
+               struct sector_ptr *sector;
 
-                       sector = rbio_stripe_sector(rbio, stripe, sectornr);
-                       /*
-                        * The bio cache may have handed us an uptodate sector.
-                        * If so, be happy and use it.
-                        */
-                       if (sector->uptodate)
-                               continue;
+               /* No data in the vertical stripe, no need to read. */
+               if (!test_bit(sectornr, &rbio->dbitmap))
+                       continue;
 
-                       ret = rbio_add_io_sector(rbio, &bio_list, sector,
-                                                stripe, sectornr, rbio->stripe_len,
-                                                REQ_OP_READ);
-                       if (ret)
-                               goto cleanup;
-               }
+               /*
+                * We want to find all the sectors missing from the rbio and
+                * read them from the disk. If sector_in_rbio() finds a sector
+                * in the bio list we don't need to read it off the stripe.
+                */
+               sector = sector_in_rbio(rbio, stripe, sectornr, 1);
+               if (sector)
+                       continue;
+
+               sector = rbio_stripe_sector(rbio, stripe, sectornr);
+               /*
+                * The bio cache may have handed us an uptodate sector.  If so,
+                * use it.
+                */
+               if (sector->uptodate)
+                       continue;
+
+               ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
+                                        sectornr, rbio->stripe_len, REQ_OP_READ);
+               if (ret)
+                       goto cleanup;
        }
 
        bios_to_read = bio_list_size(&bio_list);