Skip to content

Commit 4fe44f9

Browse files
adam900710kdave
authored andcommitted
btrfs: scrub: move write back of repaired sectors to scrub_stripe_read_repair_worker()
Currently the scrub_stripe_read_repair_worker() only does reads to rebuild the corrupted sectors, it doesn't do any writeback. The design is mostly to put writeback into a more ordered manner, to co-operate with dev-replace with zoned mode, which requires every write to be submitted in their bytenr order. However the writeback for repaired sectors into the original mirror doesn't need such strong sync requirement, as it can only happen for non-zoned devices. This patch would move the writeback for repaired sectors into scrub_stripe_read_repair_worker(), which removes two calls sites for repaired sectors writeback. (one from flush_scrub_stripes(), one from scrub_raid56_parity_stripe()) Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 39dc7bd commit 4fe44f9

File tree

1 file changed

+25
-47
lines changed

1 file changed

+25
-47
lines changed

fs/btrfs/scrub.c

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,9 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
990990
spin_unlock(&sctx->stat_lock);
991991
}
992992

993+
static void scrub_write_sectors(struct scrub_ctx *sctx, struct scrub_stripe *stripe,
994+
unsigned long write_bitmap, bool dev_replace);
995+
993996
/*
994997
* The main entrance for all read related scrub work, including:
995998
*
@@ -998,13 +1001,16 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
9981001
* - Go through the remaining mirrors and try to read as large blocksize as
9991002
* possible
10001003
* - Go through all mirrors (including the failed mirror) sector-by-sector
1004+
* - Submit writeback for repaired sectors
10011005
*
1002-
* Writeback does not happen here, it needs extra synchronization.
1006+
* Writeback for dev-replace does not happen here, it needs extra
1007+
* synchronization for zoned devices.
10031008
*/
10041009
static void scrub_stripe_read_repair_worker(struct work_struct *work)
10051010
{
10061011
struct scrub_stripe *stripe = container_of(work, struct scrub_stripe, work);
1007-
struct btrfs_fs_info *fs_info = stripe->bg->fs_info;
1012+
struct scrub_ctx *sctx = stripe->sctx;
1013+
struct btrfs_fs_info *fs_info = sctx->fs_info;
10081014
int num_copies = btrfs_num_copies(fs_info, stripe->bg->start,
10091015
stripe->bg->length);
10101016
int mirror;
@@ -1069,7 +1075,23 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
10691075
goto out;
10701076
}
10711077
out:
1072-
scrub_stripe_report_errors(stripe->sctx, stripe);
1078+
/*
1079+
* Submit the repaired sectors. For zoned case, we cannot do repair
1080+
* in-place, but queue the bg to be relocated.
1081+
*/
1082+
if (btrfs_is_zoned(fs_info)) {
1083+
if (!bitmap_empty(&stripe->error_bitmap, stripe->nr_sectors))
1084+
btrfs_repair_one_zone(fs_info, sctx->stripes[0].bg->start);
1085+
} else if (!sctx->readonly) {
1086+
unsigned long repaired;
1087+
1088+
bitmap_andnot(&repaired, &stripe->init_error_bitmap,
1089+
&stripe->error_bitmap, stripe->nr_sectors);
1090+
scrub_write_sectors(sctx, stripe, repaired, false);
1091+
wait_scrub_stripe_io(stripe);
1092+
}
1093+
1094+
scrub_stripe_report_errors(sctx, stripe);
10731095
set_bit(SCRUB_STRIPE_FLAG_REPAIR_DONE, &stripe->state);
10741096
wake_up(&stripe->repair_wait);
10751097
}
@@ -1720,32 +1742,6 @@ static int flush_scrub_stripes(struct scrub_ctx *sctx)
17201742
test_bit(SCRUB_STRIPE_FLAG_REPAIR_DONE, &stripe->state));
17211743
}
17221744

1723-
/*
1724-
* Submit the repaired sectors. For zoned case, we cannot do repair
1725-
* in-place, but queue the bg to be relocated.
1726-
*/
1727-
if (btrfs_is_zoned(fs_info)) {
1728-
for (int i = 0; i < nr_stripes; i++) {
1729-
stripe = &sctx->stripes[i];
1730-
1731-
if (!bitmap_empty(&stripe->error_bitmap, stripe->nr_sectors)) {
1732-
btrfs_repair_one_zone(fs_info,
1733-
sctx->stripes[0].bg->start);
1734-
break;
1735-
}
1736-
}
1737-
} else if (!sctx->readonly) {
1738-
for (int i = 0; i < nr_stripes; i++) {
1739-
unsigned long repaired;
1740-
1741-
stripe = &sctx->stripes[i];
1742-
1743-
bitmap_andnot(&repaired, &stripe->init_error_bitmap,
1744-
&stripe->error_bitmap, stripe->nr_sectors);
1745-
scrub_write_sectors(sctx, stripe, repaired, false);
1746-
}
1747-
}
1748-
17491745
/* Submit for dev-replace. */
17501746
if (sctx->is_dev_replace) {
17511747
/*
@@ -1918,24 +1914,6 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
19181914
/* For now, no zoned support for RAID56. */
19191915
ASSERT(!btrfs_is_zoned(sctx->fs_info));
19201916

1921-
/* Writeback for the repaired sectors. */
1922-
for (int i = 0; i < data_stripes; i++) {
1923-
unsigned long repaired;
1924-
1925-
stripe = &sctx->raid56_data_stripes[i];
1926-
1927-
bitmap_andnot(&repaired, &stripe->init_error_bitmap,
1928-
&stripe->error_bitmap, stripe->nr_sectors);
1929-
scrub_write_sectors(sctx, stripe, repaired, false);
1930-
}
1931-
1932-
/* Wait for the above writebacks to finish. */
1933-
for (int i = 0; i < data_stripes; i++) {
1934-
stripe = &sctx->raid56_data_stripes[i];
1935-
1936-
wait_scrub_stripe_io(stripe);
1937-
}
1938-
19391917
/*
19401918
* Now all data stripes are properly verified. Check if we have any
19411919
* unrepaired, if so abort immediately or we could further corrupt the

0 commit comments

Comments
 (0)