Commit ace9e12d authored by Linus Torvalds's avatar Linus Torvalds

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
parents 858fd168 79b8ee70
...@@ -242,7 +242,6 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb, ...@@ -242,7 +242,6 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb,
int mirror_num) int mirror_num)
{ {
struct btrfs_fs_info *fs_info = eb->fs_info; struct btrfs_fs_info *fs_info = eb->fs_info;
u64 start = eb->start;
int i, num_pages = num_extent_pages(eb); int i, num_pages = num_extent_pages(eb);
int ret = 0; int ret = 0;
...@@ -251,12 +250,14 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb, ...@@ -251,12 +250,14 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb,
for (i = 0; i < num_pages; i++) { for (i = 0; i < num_pages; i++) {
struct page *p = eb->pages[i]; struct page *p = eb->pages[i];
u64 start = max_t(u64, eb->start, page_offset(p));
u64 end = min_t(u64, eb->start + eb->len, page_offset(p) + PAGE_SIZE);
u32 len = end - start;
ret = btrfs_repair_io_failure(fs_info, 0, start, PAGE_SIZE, ret = btrfs_repair_io_failure(fs_info, 0, start, len,
start, p, start - page_offset(p), mirror_num); start, p, offset_in_page(start), mirror_num);
if (ret) if (ret)
break; break;
start += PAGE_SIZE;
} }
return ret; return ret;
......
...@@ -134,8 +134,14 @@ struct scrub_stripe { ...@@ -134,8 +134,14 @@ struct scrub_stripe {
* The errors hit during the initial read of the stripe. * The errors hit during the initial read of the stripe.
* *
* Would be utilized for error reporting and repair. * Would be utilized for error reporting and repair.
*
* The remaining init_nr_* records the number of errors hit, only used
* by error reporting.
*/ */
unsigned long init_error_bitmap; unsigned long init_error_bitmap;
unsigned int init_nr_io_errors;
unsigned int init_nr_csum_errors;
unsigned int init_nr_meta_errors;
/* /*
* The following error bitmaps are all for the current status. * The following error bitmaps are all for the current status.
...@@ -1003,12 +1009,9 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx, ...@@ -1003,12 +1009,9 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
sctx->stat.data_bytes_scrubbed += nr_data_sectors << fs_info->sectorsize_bits; sctx->stat.data_bytes_scrubbed += nr_data_sectors << fs_info->sectorsize_bits;
sctx->stat.tree_bytes_scrubbed += nr_meta_sectors << fs_info->sectorsize_bits; sctx->stat.tree_bytes_scrubbed += nr_meta_sectors << fs_info->sectorsize_bits;
sctx->stat.no_csum += nr_nodatacsum_sectors; sctx->stat.no_csum += nr_nodatacsum_sectors;
sctx->stat.read_errors += sctx->stat.read_errors += stripe->init_nr_io_errors;
bitmap_weight(&stripe->io_error_bitmap, stripe->nr_sectors); sctx->stat.csum_errors += stripe->init_nr_csum_errors;
sctx->stat.csum_errors += sctx->stat.verify_errors += stripe->init_nr_meta_errors;
bitmap_weight(&stripe->csum_error_bitmap, stripe->nr_sectors);
sctx->stat.verify_errors +=
bitmap_weight(&stripe->meta_error_bitmap, stripe->nr_sectors);
sctx->stat.uncorrectable_errors += sctx->stat.uncorrectable_errors +=
bitmap_weight(&stripe->error_bitmap, stripe->nr_sectors); bitmap_weight(&stripe->error_bitmap, stripe->nr_sectors);
sctx->stat.corrected_errors += nr_repaired_sectors; sctx->stat.corrected_errors += nr_repaired_sectors;
...@@ -1041,6 +1044,12 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work) ...@@ -1041,6 +1044,12 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
scrub_verify_one_stripe(stripe, stripe->extent_sector_bitmap); scrub_verify_one_stripe(stripe, stripe->extent_sector_bitmap);
/* Save the initial failed bitmap for later repair and report usage. */ /* Save the initial failed bitmap for later repair and report usage. */
stripe->init_error_bitmap = stripe->error_bitmap; stripe->init_error_bitmap = stripe->error_bitmap;
stripe->init_nr_io_errors = bitmap_weight(&stripe->io_error_bitmap,
stripe->nr_sectors);
stripe->init_nr_csum_errors = bitmap_weight(&stripe->csum_error_bitmap,
stripe->nr_sectors);
stripe->init_nr_meta_errors = bitmap_weight(&stripe->meta_error_bitmap,
stripe->nr_sectors);
if (bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors)) if (bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors))
goto out; goto out;
...@@ -1490,6 +1499,9 @@ static void scrub_stripe_reset_bitmaps(struct scrub_stripe *stripe) ...@@ -1490,6 +1499,9 @@ static void scrub_stripe_reset_bitmaps(struct scrub_stripe *stripe)
{ {
stripe->extent_sector_bitmap = 0; stripe->extent_sector_bitmap = 0;
stripe->init_error_bitmap = 0; stripe->init_error_bitmap = 0;
stripe->init_nr_io_errors = 0;
stripe->init_nr_csum_errors = 0;
stripe->init_nr_meta_errors = 0;
stripe->error_bitmap = 0; stripe->error_bitmap = 0;
stripe->io_error_bitmap = 0; stripe->io_error_bitmap = 0;
stripe->csum_error_bitmap = 0; stripe->csum_error_bitmap = 0;
...@@ -1730,7 +1742,7 @@ static int flush_scrub_stripes(struct scrub_ctx *sctx) ...@@ -1730,7 +1742,7 @@ static int flush_scrub_stripes(struct scrub_ctx *sctx)
break; break;
} }
} }
} else { } else if (!sctx->readonly) {
for (int i = 0; i < nr_stripes; i++) { for (int i = 0; i < nr_stripes; i++) {
unsigned long repaired; unsigned long repaired;
......
...@@ -1841,6 +1841,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) ...@@ -1841,6 +1841,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
btrfs_clear_sb_rdonly(sb); btrfs_clear_sb_rdonly(sb);
set_bit(BTRFS_FS_OPEN, &fs_info->flags); set_bit(BTRFS_FS_OPEN, &fs_info->flags);
/*
* If we've gone from readonly -> read/write, we need to get
* our sync/async discard lists in the right state.
*/
btrfs_discard_resume(fs_info);
} }
out: out:
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment