Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c66abba authored by Song Liu's avatar Song Liu Committed by Shaohua Li
Browse files

md/r5cache: simplify handling of sh->log_start in recovery



We only need to update sh->log_start at the end of recovery,
which is r5c_recovery_rewrite_data_only_stripes(), so it is not
necessary to set it before that. In this patch, log_start is
removed from r5c_recovery_alloc_stripe().

After updating all sh->log_start, rewrite_data_only_stripes()
also updates log->next_checkpoints to the last sh->log_start.

Signed-off-by: default avatarSong Liu <songliubraving@fb.com>
Signed-off-by: default avatarShaohua Li <shli@fb.com>
parent 28ca833e
Loading
Loading
Loading
Loading
+12 −15
Original line number Diff line number Diff line
@@ -1682,8 +1682,7 @@ r5l_recovery_replay_one_stripe(struct r5conf *conf,

static struct stripe_head *
r5c_recovery_alloc_stripe(struct r5conf *conf,
			  sector_t stripe_sect,
			  sector_t log_start)
			  sector_t stripe_sect)
{
	struct stripe_head *sh;

@@ -1692,7 +1691,6 @@ r5c_recovery_alloc_stripe(struct r5conf *conf,
		return NULL;  /* no more stripe available */

	r5l_recovery_reset_stripe(sh);
	sh->log_start = log_start;

	return sh;
}
@@ -1862,7 +1860,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
						stripe_sect);

		if (!sh) {
			sh = r5c_recovery_alloc_stripe(conf, stripe_sect, ctx->pos);
			sh = r5c_recovery_alloc_stripe(conf, stripe_sect);
			/*
			 * cannot get stripe from raid5_get_active_stripe
			 * try replay some stripes
@@ -1871,7 +1869,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
				r5c_recovery_replay_stripes(
					cached_stripe_list, ctx);
				sh = r5c_recovery_alloc_stripe(
					conf, stripe_sect, ctx->pos);
					conf, stripe_sect);
			}
			if (!sh) {
				pr_debug("md/raid:%s: Increasing stripe cache size to %d to recovery data on journal.\n",
@@ -1879,8 +1877,8 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
					conf->min_nr_stripes * 2);
				raid5_set_cache_size(mddev,
						     conf->min_nr_stripes * 2);
				sh = r5c_recovery_alloc_stripe(
					conf, stripe_sect, ctx->pos);
				sh = r5c_recovery_alloc_stripe(conf,
							       stripe_sect);
			}
			if (!sh) {
				pr_err("md/raid:%s: Cannot get enough stripes due to memory pressure. Recovery failed.\n",
@@ -1894,7 +1892,6 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
			if (!test_bit(STRIPE_R5C_CACHING, &sh->state) &&
			    test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags)) {
				r5l_recovery_replay_one_stripe(conf, sh, ctx);
				sh->log_start = ctx->pos;
				list_move_tail(&sh->lru, cached_stripe_list);
			}
			r5l_recovery_load_data(log, sh, ctx, payload,
@@ -1933,8 +1930,6 @@ static void r5c_recovery_load_one_stripe(struct r5l_log *log,
			set_bit(R5_UPTODATE, &dev->flags);
		}
	}
	list_add_tail(&sh->r5c, &log->stripe_in_journal_list);
	atomic_inc(&log->stripe_in_journal_count);
}

/*
@@ -2070,6 +2065,7 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
	struct stripe_head *sh, *next;
	struct mddev *mddev = log->rdev->mddev;
	struct page *page;
	sector_t next_checkpoint = MaxSector;

	page = alloc_page(GFP_KERNEL);
	if (!page) {
@@ -2078,6 +2074,8 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
		return -ENOMEM;
	}

	WARN_ON(list_empty(&ctx->cached_list));

	list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) {
		struct r5l_meta_block *mb;
		int i;
@@ -2123,12 +2121,15 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
		sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page,
			     REQ_OP_WRITE, REQ_FUA, false);
		sh->log_start = ctx->pos;
		list_add_tail(&sh->r5c, &log->stripe_in_journal_list);
		atomic_inc(&log->stripe_in_journal_count);
		ctx->pos = write_pos;
		ctx->seq += 1;

		next_checkpoint = sh->log_start;
		list_del_init(&sh->lru);
		raid5_release_stripe(sh);
	}
	log->next_checkpoint = next_checkpoint;
	__free_page(page);
	return 0;
}
@@ -2139,7 +2140,6 @@ static int r5l_recovery_log(struct r5l_log *log)
	struct r5l_recovery_ctx ctx;
	int ret;
	sector_t pos;
	struct stripe_head *sh;

	ctx.pos = log->last_checkpoint;
	ctx.seq = log->last_cp_seq;
@@ -2164,9 +2164,6 @@ static int r5l_recovery_log(struct r5l_log *log)
		log->next_checkpoint = ctx.pos;
		r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq++);
		ctx.pos = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS);
	} else {
		sh = list_last_entry(&ctx.cached_list, struct stripe_head, lru);
		log->next_checkpoint = sh->log_start;
	}

	if ((ctx.data_only_stripes == 0) && (ctx.data_parity_stripes == 0))