mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-12 23:13:12 -04:00
btrfs: scrub: move error reporting members to stack
Currently the following members of scrub_stripe are only utilized for error reporting: - init_error_bitmap - init_nr_io_errors - init_nr_csum_errors - init_nr_meta_errors - init_nr_meta_gen_errors There is no need to put all those members into scrub_stripe, which take 24 bytes for each stripe, and we have 128 stripes for each device. Instead introduce a structure, scrub_error_records, and move all above members into that structure. And allocate such structure from stack inside scrub_stripe_read_repair_worker(). Since that function is called from a workqueue context, we have more than enough stack space for just 24 bytes. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
@@ -141,20 +141,6 @@ struct scrub_stripe {
|
||||
/* Indicate which sectors are covered by extent items. */
|
||||
unsigned long extent_sector_bitmap;
|
||||
|
||||
/*
|
||||
* The errors hit during the initial read of the stripe.
|
||||
*
|
||||
* 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 int init_nr_io_errors;
|
||||
unsigned int init_nr_csum_errors;
|
||||
unsigned int init_nr_meta_errors;
|
||||
unsigned int init_nr_meta_gen_errors;
|
||||
|
||||
/*
|
||||
* The following error bitmaps are all for the current status.
|
||||
* Every time we submit a new read, these bitmaps may be updated.
|
||||
@@ -231,6 +217,19 @@ struct scrub_warning {
|
||||
struct btrfs_device *dev;
|
||||
};
|
||||
|
||||
struct scrub_error_records {
|
||||
/*
|
||||
* Bitmap recording which blocks hit errors (IO/csum/...) during the
|
||||
* initial read.
|
||||
*/
|
||||
unsigned long init_error_bitmap;
|
||||
|
||||
unsigned int nr_io_errors;
|
||||
unsigned int nr_csum_errors;
|
||||
unsigned int nr_meta_errors;
|
||||
unsigned int nr_meta_gen_errors;
|
||||
};
|
||||
|
||||
static void release_scrub_stripe(struct scrub_stripe *stripe)
|
||||
{
|
||||
if (!stripe)
|
||||
@@ -867,7 +866,8 @@ static void scrub_stripe_submit_repair_read(struct scrub_stripe *stripe,
|
||||
}
|
||||
|
||||
static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
||||
struct scrub_stripe *stripe)
|
||||
struct scrub_stripe *stripe,
|
||||
const struct scrub_error_records *errors)
|
||||
{
|
||||
static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
|
||||
DEFAULT_RATELIMIT_BURST);
|
||||
@@ -889,7 +889,7 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
||||
* Although our scrub_stripe infrastructure is mostly based on btrfs_submit_bio()
|
||||
* thus no need for dev/physical, error reporting still needs dev and physical.
|
||||
*/
|
||||
if (!bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors)) {
|
||||
if (!bitmap_empty(&errors->init_error_bitmap, stripe->nr_sectors)) {
|
||||
u64 mapped_len = fs_info->sectorsize;
|
||||
struct btrfs_io_context *bioc = NULL;
|
||||
int stripe_index = stripe->mirror_num - 1;
|
||||
@@ -923,14 +923,14 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
||||
nr_nodatacsum_sectors++;
|
||||
}
|
||||
|
||||
if (test_bit(sector_nr, &stripe->init_error_bitmap) &&
|
||||
if (test_bit(sector_nr, &errors->init_error_bitmap) &&
|
||||
!test_bit(sector_nr, &stripe->error_bitmap)) {
|
||||
nr_repaired_sectors++;
|
||||
repaired = true;
|
||||
}
|
||||
|
||||
/* Good sector from the beginning, nothing need to be done. */
|
||||
if (!test_bit(sector_nr, &stripe->init_error_bitmap))
|
||||
if (!test_bit(sector_nr, &errors->init_error_bitmap))
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -982,12 +982,12 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
||||
}
|
||||
|
||||
/* Update the device stats. */
|
||||
for (int i = 0; i < stripe->init_nr_io_errors; i++)
|
||||
for (int i = 0; i < errors->nr_io_errors; i++)
|
||||
btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_READ_ERRS);
|
||||
for (int i = 0; i < stripe->init_nr_csum_errors; i++)
|
||||
for (int i = 0; i < errors->nr_csum_errors; i++)
|
||||
btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_CORRUPTION_ERRS);
|
||||
/* Generation mismatch error is based on each metadata, not each block. */
|
||||
for (int i = 0; i < stripe->init_nr_meta_gen_errors;
|
||||
for (int i = 0; i < errors->nr_meta_gen_errors;
|
||||
i += (fs_info->nodesize >> fs_info->sectorsize_bits))
|
||||
btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_GENERATION_ERRS);
|
||||
|
||||
@@ -997,10 +997,10 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
||||
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.no_csum += nr_nodatacsum_sectors;
|
||||
sctx->stat.read_errors += stripe->init_nr_io_errors;
|
||||
sctx->stat.csum_errors += stripe->init_nr_csum_errors;
|
||||
sctx->stat.verify_errors += stripe->init_nr_meta_errors +
|
||||
stripe->init_nr_meta_gen_errors;
|
||||
sctx->stat.read_errors += errors->nr_io_errors;
|
||||
sctx->stat.csum_errors += errors->nr_csum_errors;
|
||||
sctx->stat.verify_errors += errors->nr_meta_errors +
|
||||
errors->nr_meta_gen_errors;
|
||||
sctx->stat.uncorrectable_errors +=
|
||||
bitmap_weight(&stripe->error_bitmap, stripe->nr_sectors);
|
||||
sctx->stat.corrected_errors += nr_repaired_sectors;
|
||||
@@ -1028,6 +1028,7 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
|
||||
struct scrub_stripe *stripe = container_of(work, struct scrub_stripe, work);
|
||||
struct scrub_ctx *sctx = stripe->sctx;
|
||||
struct btrfs_fs_info *fs_info = sctx->fs_info;
|
||||
struct scrub_error_records errors = { 0 };
|
||||
int num_copies = btrfs_num_copies(fs_info, stripe->bg->start,
|
||||
stripe->bg->length);
|
||||
unsigned long repaired;
|
||||
@@ -1039,17 +1040,17 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
|
||||
wait_scrub_stripe_io(stripe);
|
||||
scrub_verify_one_stripe(stripe, stripe->extent_sector_bitmap);
|
||||
/* Save the initial failed bitmap for later repair and report usage. */
|
||||
stripe->init_error_bitmap = stripe->error_bitmap;
|
||||
stripe->init_nr_io_errors = bitmap_weight(&stripe->io_error_bitmap,
|
||||
errors.init_error_bitmap = stripe->error_bitmap;
|
||||
errors.nr_io_errors = bitmap_weight(&stripe->io_error_bitmap,
|
||||
stripe->nr_sectors);
|
||||
errors.nr_csum_errors = bitmap_weight(&stripe->csum_error_bitmap,
|
||||
stripe->nr_sectors);
|
||||
errors.nr_meta_errors = bitmap_weight(&stripe->meta_error_bitmap,
|
||||
stripe->nr_sectors);
|
||||
errors.nr_meta_gen_errors = bitmap_weight(&stripe->meta_gen_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);
|
||||
stripe->init_nr_meta_gen_errors = bitmap_weight(&stripe->meta_gen_error_bitmap,
|
||||
stripe->nr_sectors);
|
||||
|
||||
if (bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors))
|
||||
if (bitmap_empty(&errors.init_error_bitmap, stripe->nr_sectors))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
@@ -1099,7 +1100,7 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
|
||||
* Submit the repaired sectors. For zoned case, we cannot do repair
|
||||
* in-place, but queue the bg to be relocated.
|
||||
*/
|
||||
bitmap_andnot(&repaired, &stripe->init_error_bitmap, &stripe->error_bitmap,
|
||||
bitmap_andnot(&repaired, &errors.init_error_bitmap, &stripe->error_bitmap,
|
||||
stripe->nr_sectors);
|
||||
if (!sctx->readonly && !bitmap_empty(&repaired, stripe->nr_sectors)) {
|
||||
if (btrfs_is_zoned(fs_info)) {
|
||||
@@ -1110,7 +1111,7 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
|
||||
scrub_stripe_report_errors(sctx, stripe);
|
||||
scrub_stripe_report_errors(sctx, stripe, &errors);
|
||||
set_bit(SCRUB_STRIPE_FLAG_REPAIR_DONE, &stripe->state);
|
||||
wake_up(&stripe->repair_wait);
|
||||
}
|
||||
@@ -1522,11 +1523,6 @@ static void fill_one_extent_info(struct btrfs_fs_info *fs_info,
|
||||
static void scrub_stripe_reset_bitmaps(struct scrub_stripe *stripe)
|
||||
{
|
||||
stripe->extent_sector_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->init_nr_meta_gen_errors = 0;
|
||||
stripe->error_bitmap = 0;
|
||||
stripe->io_error_bitmap = 0;
|
||||
stripe->csum_error_bitmap = 0;
|
||||
|
||||
Reference in New Issue
Block a user