From: "Jackie Liu" <liuyun01@kylinos.cn>
To: "Song Liu" <songliubraving@fb.com>
Cc: linux-raid <linux-raid@vger.kernel.org>,
刘正元 <liuzhengyuan@kylinos.cn>, shli <shli@fb.com>
Subject: [PATCH] raid5-cache: Fix the logic of raid5-cache recovery
Date: Fri, 25 Nov 2016 19:39:03 +0800 [thread overview]
Message-ID: <tencent_4E54374D19A73C0B4D37AF14@qq.com> (raw)
In-Reply-To: <20161119072057.1302854-1-songliubraving@fb.com>
Hi Song.
There is a doubt for r5l_recovery_log. I think we need write an empty block first,
then call r5c_recovery_rewrite_data_only_stripes functions. this empty
block will be mark as the last_checkpoint. when the CACHING block is rewritten,
the superblock should be update this time. at the same time, we cann't be
released the stripe_head at the front, it also be used in
r5c_recovery_rewrite_data_only_stripes.
here is the patch
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 5f817bd..fad1808 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -67,7 +67,7 @@ static char *r5c_journal_mode_str[] = {"write-through",
/*
* raid5 cache state machine
*
- * With rhe RAID cache, each stripe works in two phases:
+ * With the RAID cache, each stripe works in two phases:
* - caching phase
* - writing-out phase
*
@@ -1674,7 +1674,6 @@ r5l_recovery_replay_one_stripe(struct r5conf *conf,
static struct stripe_head *
r5c_recovery_alloc_stripe(struct r5conf *conf,
- struct list_head *recovery_list,
sector_t stripe_sect,
sector_t log_start)
{
@@ -1855,8 +1854,8 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
stripe_sect);
if (!sh) {
- sh = r5c_recovery_alloc_stripe(conf, cached_stripe_list,
- stripe_sect, ctx->pos);
+ sh = r5c_recovery_alloc_stripe(conf, stripe_sect,
+ ctx->pos);
/*
* cannot get stripe from raid5_get_active_stripe
* try replay some stripes
@@ -1865,8 +1864,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
r5c_recovery_replay_stripes(
cached_stripe_list, ctx);
sh = r5c_recovery_alloc_stripe(
- conf, cached_stripe_list,
- stripe_sect, ctx->pos);
+ conf, stripe_sect, ctx->pos);
}
if (!sh) {
pr_debug("md/raid:%s: Increasing stripe cache size to %d to recovery data on journal.\n",
@@ -1875,8 +1873,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
raid5_set_cache_size(mddev,
conf->min_nr_stripes * 2);
sh = r5c_recovery_alloc_stripe(
- conf, cached_stripe_list, stripe_sect,
- ctx->pos);
+ conf, stripe_sect, ctx->pos);
}
if (!sh) {
pr_err("md/raid:%s: Cannot get enough stripes due to memory pressure. Recovery failed.\n",
@@ -1986,8 +1983,6 @@ static int r5c_recovery_flush_log(struct r5l_log *log,
list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) {
WARN_ON(!test_bit(STRIPE_R5C_CACHING, &sh->state));
r5c_recovery_load_one_stripe(log, sh);
- list_del_init(&sh->lru);
- raid5_release_stripe(sh);
ctx->data_only_stripes++;
}
@@ -2078,7 +2073,6 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
return -ENOMEM;
}
- ctx->seq += 10;
list_for_each_entry(sh, &ctx->cached_list, lru) {
struct r5l_meta_block *mb;
int i;
@@ -2090,7 +2084,7 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
ctx->pos, ctx->seq);
mb = page_address(page);
offset = le32_to_cpu(mb->meta_size);
- write_pos = ctx->pos + BLOCK_SECTORS;
+ write_pos = r5l_ring_add(log, ctx->pos, BLOCK_SECTORS);
for (i = sh->disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
@@ -2125,6 +2119,9 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
sh->log_start = ctx->pos;
ctx->pos = write_pos;
ctx->seq += 1;
+
+ list_del_init(&sh->lru);
+ raid5_release_stripe(sh);
}
__free_page(page);
return 0;
@@ -2135,6 +2132,7 @@ static int r5l_recovery_log(struct r5l_log *log)
struct mddev *mddev = log->rdev->mddev;
struct r5l_recovery_ctx ctx;
int ret;
+ sector_t pos;
ctx.pos = log->last_checkpoint;
ctx.seq = log->last_cp_seq;
@@ -2152,6 +2150,10 @@ static int r5l_recovery_log(struct r5l_log *log)
if (ret)
return ret;
+ pos = ctx.pos;
+ r5l_log_write_empty_meta_block(log, ctx.pos, (ctx.seq += 10));
+ ctx.pos = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS);
+
if ((ctx.data_only_stripes == 0) && (ctx.data_parity_stripes == 0))
pr_debug("md/raid:%s: starting from clean shutdown\n",
mdname(mddev));
@@ -2170,9 +2172,9 @@ static int r5l_recovery_log(struct r5l_log *log)
log->log_start = ctx.pos;
log->next_checkpoint = ctx.pos;
+ log->last_checkpoint = pos;
log->seq = ctx.seq;
- r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq);
- r5l_write_super(log, ctx.pos);
+ r5l_write_super(log, pos);
return 0;
}
--
2.7.4
Thanks.
Jackie
next prev parent reply other threads:[~2016-11-25 11:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-19 7:20 [PATCH] md/r5cache: handle alloc_page failure Song Liu
2016-11-21 5:05 ` NeilBrown
2016-11-25 11:39 ` Jackie Liu [this message]
2016-11-27 23:36 ` [PATCH] raid5-cache: Fix the logic of raid5-cache recovery Song Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tencent_4E54374D19A73C0B4D37AF14@qq.com \
--to=liuyun01@kylinos.cn \
--cc=linux-raid@vger.kernel.org \
--cc=liuzhengyuan@kylinos.cn \
--cc=shli@fb.com \
--cc=songliubraving@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).