Skip to content

Commit ace9e12

Browse files
committed
Merge tag 'for-6.4-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "A more fixes and regression fixes: - in subpage mode, fix crash when repairing metadata at the end of a stripe - properly enable async discard when remounting from read-only to read-write - scrub regression fixes: - respect read-only scrub when attempting to do a repair - fix reporting of found errors, the stats don't get properly accounted after a stripe repair" * tag 'for-6.4-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: scrub: also report errors hit during the initial read btrfs: scrub: respect the read-only flag during repair btrfs: properly enable async discard when switching from RO->RW btrfs: subpage: fix a crash in metadata repair path
2 parents 858fd16 + 79b8ee7 commit ace9e12

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

fs/btrfs/disk-io.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb,
242242
int mirror_num)
243243
{
244244
struct btrfs_fs_info *fs_info = eb->fs_info;
245-
u64 start = eb->start;
246245
int i, num_pages = num_extent_pages(eb);
247246
int ret = 0;
248247

@@ -251,12 +250,14 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb,
251250

252251
for (i = 0; i < num_pages; i++) {
253252
struct page *p = eb->pages[i];
253+
u64 start = max_t(u64, eb->start, page_offset(p));
254+
u64 end = min_t(u64, eb->start + eb->len, page_offset(p) + PAGE_SIZE);
255+
u32 len = end - start;
254256

255-
ret = btrfs_repair_io_failure(fs_info, 0, start, PAGE_SIZE,
256-
start, p, start - page_offset(p), mirror_num);
257+
ret = btrfs_repair_io_failure(fs_info, 0, start, len,
258+
start, p, offset_in_page(start), mirror_num);
257259
if (ret)
258260
break;
259-
start += PAGE_SIZE;
260261
}
261262

262263
return ret;

fs/btrfs/scrub.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,14 @@ struct scrub_stripe {
134134
* The errors hit during the initial read of the stripe.
135135
*
136136
* Would be utilized for error reporting and repair.
137+
*
138+
* The remaining init_nr_* records the number of errors hit, only used
139+
* by error reporting.
137140
*/
138141
unsigned long init_error_bitmap;
142+
unsigned int init_nr_io_errors;
143+
unsigned int init_nr_csum_errors;
144+
unsigned int init_nr_meta_errors;
139145

140146
/*
141147
* The following error bitmaps are all for the current status.
@@ -1003,12 +1009,9 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
10031009
sctx->stat.data_bytes_scrubbed += nr_data_sectors << fs_info->sectorsize_bits;
10041010
sctx->stat.tree_bytes_scrubbed += nr_meta_sectors << fs_info->sectorsize_bits;
10051011
sctx->stat.no_csum += nr_nodatacsum_sectors;
1006-
sctx->stat.read_errors +=
1007-
bitmap_weight(&stripe->io_error_bitmap, stripe->nr_sectors);
1008-
sctx->stat.csum_errors +=
1009-
bitmap_weight(&stripe->csum_error_bitmap, stripe->nr_sectors);
1010-
sctx->stat.verify_errors +=
1011-
bitmap_weight(&stripe->meta_error_bitmap, stripe->nr_sectors);
1012+
sctx->stat.read_errors += stripe->init_nr_io_errors;
1013+
sctx->stat.csum_errors += stripe->init_nr_csum_errors;
1014+
sctx->stat.verify_errors += stripe->init_nr_meta_errors;
10121015
sctx->stat.uncorrectable_errors +=
10131016
bitmap_weight(&stripe->error_bitmap, stripe->nr_sectors);
10141017
sctx->stat.corrected_errors += nr_repaired_sectors;
@@ -1041,6 +1044,12 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
10411044
scrub_verify_one_stripe(stripe, stripe->extent_sector_bitmap);
10421045
/* Save the initial failed bitmap for later repair and report usage. */
10431046
stripe->init_error_bitmap = stripe->error_bitmap;
1047+
stripe->init_nr_io_errors = bitmap_weight(&stripe->io_error_bitmap,
1048+
stripe->nr_sectors);
1049+
stripe->init_nr_csum_errors = bitmap_weight(&stripe->csum_error_bitmap,
1050+
stripe->nr_sectors);
1051+
stripe->init_nr_meta_errors = bitmap_weight(&stripe->meta_error_bitmap,
1052+
stripe->nr_sectors);
10441053

10451054
if (bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors))
10461055
goto out;
@@ -1490,6 +1499,9 @@ static void scrub_stripe_reset_bitmaps(struct scrub_stripe *stripe)
14901499
{
14911500
stripe->extent_sector_bitmap = 0;
14921501
stripe->init_error_bitmap = 0;
1502+
stripe->init_nr_io_errors = 0;
1503+
stripe->init_nr_csum_errors = 0;
1504+
stripe->init_nr_meta_errors = 0;
14931505
stripe->error_bitmap = 0;
14941506
stripe->io_error_bitmap = 0;
14951507
stripe->csum_error_bitmap = 0;
@@ -1730,7 +1742,7 @@ static int flush_scrub_stripes(struct scrub_ctx *sctx)
17301742
break;
17311743
}
17321744
}
1733-
} else {
1745+
} else if (!sctx->readonly) {
17341746
for (int i = 0; i < nr_stripes; i++) {
17351747
unsigned long repaired;
17361748

fs/btrfs/super.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,6 +1841,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
18411841
btrfs_clear_sb_rdonly(sb);
18421842

18431843
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
1844+
1845+
/*
1846+
* If we've gone from readonly -> read/write, we need to get
1847+
* our sync/async discard lists in the right state.
1848+
*/
1849+
btrfs_discard_resume(fs_info);
18441850
}
18451851
out:
18461852
/*

0 commit comments

Comments
 (0)