OSDN Git Service

btrfs: scrub: move write back of repaired sectors to scrub_stripe_read_repair_worker()
[tomoyo/tomoyo-test1.git] / fs / btrfs / scrub.c
index ff2d8b8..b877203 100644 (file)
@@ -990,6 +990,9 @@ skip:
        spin_unlock(&sctx->stat_lock);
 }
 
+static void scrub_write_sectors(struct scrub_ctx *sctx, struct scrub_stripe *stripe,
+                               unsigned long write_bitmap, bool dev_replace);
+
 /*
  * The main entrance for all read related scrub work, including:
  *
@@ -998,13 +1001,16 @@ skip:
  * - Go through the remaining mirrors and try to read as large blocksize as
  *   possible
  * - Go through all mirrors (including the failed mirror) sector-by-sector
+ * - Submit writeback for repaired sectors
  *
- * Writeback does not happen here, it needs extra synchronization.
+ * Writeback for dev-replace does not happen here, it needs extra
+ * synchronization for zoned devices.
  */
 static void scrub_stripe_read_repair_worker(struct work_struct *work)
 {
        struct scrub_stripe *stripe = container_of(work, struct scrub_stripe, work);
-       struct btrfs_fs_info *fs_info = stripe->bg->fs_info;
+       struct scrub_ctx *sctx = stripe->sctx;
+       struct btrfs_fs_info *fs_info = sctx->fs_info;
        int num_copies = btrfs_num_copies(fs_info, stripe->bg->start,
                                          stripe->bg->length);
        int mirror;
@@ -1069,7 +1075,23 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
                        goto out;
        }
 out:
-       scrub_stripe_report_errors(stripe->sctx, stripe);
+       /*
+        * Submit the repaired sectors.  For zoned case, we cannot do repair
+        * in-place, but queue the bg to be relocated.
+        */
+       if (btrfs_is_zoned(fs_info)) {
+               if (!bitmap_empty(&stripe->error_bitmap, stripe->nr_sectors))
+                       btrfs_repair_one_zone(fs_info, sctx->stripes[0].bg->start);
+       } else if (!sctx->readonly) {
+               unsigned long repaired;
+
+               bitmap_andnot(&repaired, &stripe->init_error_bitmap,
+                             &stripe->error_bitmap, stripe->nr_sectors);
+               scrub_write_sectors(sctx, stripe, repaired, false);
+               wait_scrub_stripe_io(stripe);
+       }
+
+       scrub_stripe_report_errors(sctx, stripe);
        set_bit(SCRUB_STRIPE_FLAG_REPAIR_DONE, &stripe->state);
        wake_up(&stripe->repair_wait);
 }
@@ -1720,32 +1742,6 @@ static int flush_scrub_stripes(struct scrub_ctx *sctx)
                           test_bit(SCRUB_STRIPE_FLAG_REPAIR_DONE, &stripe->state));
        }
 
-       /*
-        * Submit the repaired sectors.  For zoned case, we cannot do repair
-        * in-place, but queue the bg to be relocated.
-        */
-       if (btrfs_is_zoned(fs_info)) {
-               for (int i = 0; i < nr_stripes; i++) {
-                       stripe = &sctx->stripes[i];
-
-                       if (!bitmap_empty(&stripe->error_bitmap, stripe->nr_sectors)) {
-                               btrfs_repair_one_zone(fs_info,
-                                                     sctx->stripes[0].bg->start);
-                               break;
-                       }
-               }
-       } else if (!sctx->readonly) {
-               for (int i = 0; i < nr_stripes; i++) {
-                       unsigned long repaired;
-
-                       stripe = &sctx->stripes[i];
-
-                       bitmap_andnot(&repaired, &stripe->init_error_bitmap,
-                                     &stripe->error_bitmap, stripe->nr_sectors);
-                       scrub_write_sectors(sctx, stripe, repaired, false);
-               }
-       }
-
        /* Submit for dev-replace. */
        if (sctx->is_dev_replace) {
                /*
@@ -1918,24 +1914,6 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
        /* For now, no zoned support for RAID56. */
        ASSERT(!btrfs_is_zoned(sctx->fs_info));
 
-       /* Writeback for the repaired sectors. */
-       for (int i = 0; i < data_stripes; i++) {
-               unsigned long repaired;
-
-               stripe = &sctx->raid56_data_stripes[i];
-
-               bitmap_andnot(&repaired, &stripe->init_error_bitmap,
-                             &stripe->error_bitmap, stripe->nr_sectors);
-               scrub_write_sectors(sctx, stripe, repaired, false);
-       }
-
-       /* Wait for the above writebacks to finish. */
-       for (int i = 0; i < data_stripes; i++) {
-               stripe = &sctx->raid56_data_stripes[i];
-
-               wait_scrub_stripe_io(stripe);
-       }
-
        /*
         * Now all data stripes are properly verified. Check if we have any
         * unrepaired, if so abort immediately or we could further corrupt the