提交 3c66abba 编写于 作者: S Song Liu 提交者: Shaohua Li

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: NSong Liu <songliubraving@fb.com>
Signed-off-by: NShaohua Li <shli@fb.com>
上级 28ca833e
...@@ -1682,8 +1682,7 @@ r5l_recovery_replay_one_stripe(struct r5conf *conf, ...@@ -1682,8 +1682,7 @@ r5l_recovery_replay_one_stripe(struct r5conf *conf,
static struct stripe_head * static struct stripe_head *
r5c_recovery_alloc_stripe(struct r5conf *conf, r5c_recovery_alloc_stripe(struct r5conf *conf,
sector_t stripe_sect, sector_t stripe_sect)
sector_t log_start)
{ {
struct stripe_head *sh; struct stripe_head *sh;
...@@ -1692,7 +1691,6 @@ r5c_recovery_alloc_stripe(struct r5conf *conf, ...@@ -1692,7 +1691,6 @@ r5c_recovery_alloc_stripe(struct r5conf *conf,
return NULL; /* no more stripe available */ return NULL; /* no more stripe available */
r5l_recovery_reset_stripe(sh); r5l_recovery_reset_stripe(sh);
sh->log_start = log_start;
return sh; return sh;
} }
...@@ -1862,7 +1860,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log, ...@@ -1862,7 +1860,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
stripe_sect); stripe_sect);
if (!sh) { 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 * cannot get stripe from raid5_get_active_stripe
* try replay some stripes * try replay some stripes
...@@ -1871,7 +1869,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log, ...@@ -1871,7 +1869,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
r5c_recovery_replay_stripes( r5c_recovery_replay_stripes(
cached_stripe_list, ctx); cached_stripe_list, ctx);
sh = r5c_recovery_alloc_stripe( sh = r5c_recovery_alloc_stripe(
conf, stripe_sect, ctx->pos); conf, stripe_sect);
} }
if (!sh) { if (!sh) {
pr_debug("md/raid:%s: Increasing stripe cache size to %d to recovery data on journal.\n", 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, ...@@ -1879,8 +1877,8 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
conf->min_nr_stripes * 2); conf->min_nr_stripes * 2);
raid5_set_cache_size(mddev, raid5_set_cache_size(mddev,
conf->min_nr_stripes * 2); conf->min_nr_stripes * 2);
sh = r5c_recovery_alloc_stripe( sh = r5c_recovery_alloc_stripe(conf,
conf, stripe_sect, ctx->pos); stripe_sect);
} }
if (!sh) { if (!sh) {
pr_err("md/raid:%s: Cannot get enough stripes due to memory pressure. Recovery failed.\n", 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, ...@@ -1894,7 +1892,6 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
if (!test_bit(STRIPE_R5C_CACHING, &sh->state) && if (!test_bit(STRIPE_R5C_CACHING, &sh->state) &&
test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags)) { test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags)) {
r5l_recovery_replay_one_stripe(conf, sh, ctx); r5l_recovery_replay_one_stripe(conf, sh, ctx);
sh->log_start = ctx->pos;
list_move_tail(&sh->lru, cached_stripe_list); list_move_tail(&sh->lru, cached_stripe_list);
} }
r5l_recovery_load_data(log, sh, ctx, payload, r5l_recovery_load_data(log, sh, ctx, payload,
...@@ -1933,8 +1930,6 @@ static void r5c_recovery_load_one_stripe(struct r5l_log *log, ...@@ -1933,8 +1930,6 @@ static void r5c_recovery_load_one_stripe(struct r5l_log *log,
set_bit(R5_UPTODATE, &dev->flags); 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, ...@@ -2070,6 +2065,7 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
struct stripe_head *sh, *next; struct stripe_head *sh, *next;
struct mddev *mddev = log->rdev->mddev; struct mddev *mddev = log->rdev->mddev;
struct page *page; struct page *page;
sector_t next_checkpoint = MaxSector;
page = alloc_page(GFP_KERNEL); page = alloc_page(GFP_KERNEL);
if (!page) { if (!page) {
...@@ -2078,6 +2074,8 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log, ...@@ -2078,6 +2074,8 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
return -ENOMEM; return -ENOMEM;
} }
WARN_ON(list_empty(&ctx->cached_list));
list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) { list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) {
struct r5l_meta_block *mb; struct r5l_meta_block *mb;
int i; int i;
...@@ -2123,12 +2121,15 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log, ...@@ -2123,12 +2121,15 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page, sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page,
REQ_OP_WRITE, REQ_FUA, false); REQ_OP_WRITE, REQ_FUA, false);
sh->log_start = ctx->pos; 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->pos = write_pos;
ctx->seq += 1; ctx->seq += 1;
next_checkpoint = sh->log_start;
list_del_init(&sh->lru); list_del_init(&sh->lru);
raid5_release_stripe(sh); raid5_release_stripe(sh);
} }
log->next_checkpoint = next_checkpoint;
__free_page(page); __free_page(page);
return 0; return 0;
} }
...@@ -2139,7 +2140,6 @@ static int r5l_recovery_log(struct r5l_log *log) ...@@ -2139,7 +2140,6 @@ static int r5l_recovery_log(struct r5l_log *log)
struct r5l_recovery_ctx ctx; struct r5l_recovery_ctx ctx;
int ret; int ret;
sector_t pos; sector_t pos;
struct stripe_head *sh;
ctx.pos = log->last_checkpoint; ctx.pos = log->last_checkpoint;
ctx.seq = log->last_cp_seq; ctx.seq = log->last_cp_seq;
...@@ -2164,9 +2164,6 @@ static int r5l_recovery_log(struct r5l_log *log) ...@@ -2164,9 +2164,6 @@ static int r5l_recovery_log(struct r5l_log *log)
log->next_checkpoint = ctx.pos; log->next_checkpoint = ctx.pos;
r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq++); r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq++);
ctx.pos = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS); 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)) if ((ctx.data_only_stripes == 0) && (ctx.data_parity_stripes == 0))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册