]> git.baikalelectronics.ru Git - kernel.git/commitdiff
btrfs: raid56: avoid double for loop inside __raid56_parity_recover()
authorQu Wenruo <wqu@suse.com>
Thu, 2 Jun 2022 07:51:19 +0000 (15:51 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 25 Jul 2022 15:45:35 +0000 (17:45 +0200)
The double for loop can be easily converted to single for loop as we're
really iterating the sectors in their bytenr order.

The only exception is the full stripe skip, however that can also easily
be done inside the loop.  Add an ASSERT() along with a comment for that
specific case.

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 c63845c036dff1cd44a553f47514124e081335d8..ae4556b98060487a1e7ce06a40d1671e2e50f1bc 100644 (file)
@@ -2115,8 +2115,7 @@ static int __raid56_parity_recover(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);
@@ -2132,29 +2131,29 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
         * stripe cache, it is possible that some or all of these
         * pages are going to be uptodate.
         */
-       for (stripe = 0; stripe < rbio->real_stripes; stripe++) {
+       for (total_sector_nr = 0; total_sector_nr < rbio->nr_sectors;
+            total_sector_nr++) {
+               int stripe = total_sector_nr / rbio->stripe_nsectors;
+               int sectornr = total_sector_nr % rbio->stripe_nsectors;
+               struct sector_ptr *sector;
+
                if (rbio->faila == stripe || rbio->failb == stripe) {
                        atomic_inc(&rbio->error);
+                       /* Skip the current stripe. */
+                       ASSERT(sectornr == 0);
+                       total_sector_nr += rbio->stripe_nsectors - 1;
                        continue;
                }
+               /* The RMW code may have already read this page in. */
+               sector = rbio_stripe_sector(rbio, stripe, sectornr);
+               if (sector->uptodate)
+                       continue;
 
-               for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) {
-                       struct sector_ptr *sector;
-
-                       /*
-                        * the rmw code may have already read this
-                        * page in
-                        */
-                       sector = rbio_stripe_sector(rbio, stripe, sectornr);
-                       if (sector->uptodate)
-                               continue;
-
-                       ret = rbio_add_io_sector(rbio, &bio_list, sector,
-                                                stripe, sectornr, rbio->stripe_len,
-                                                REQ_OP_READ);
-                       if (ret < 0)
-                               goto cleanup;
-               }
+               ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
+                                        sectornr, rbio->stripe_len,
+                                        REQ_OP_READ);
+               if (ret < 0)
+                       goto cleanup;
        }
 
        bios_to_read = bio_list_size(&bio_list);