mirror of https://gitee.com/openkylin/linux.git
md/raid5-cache: adjust the write position of the empty block if no data blocks
When recovery is complete, we write an empty block and record his position first, then make the data-only stripes rewritten done, the location of the empty block as the last checkpoint position to write into the super block. And we should update last_checkpoint to this empty block position. ------------------------------------------------------------------ | old log | empty block | data only stripes | invalid log | ------------------------------------------------------------------ ^ ^ ^ | |- log->last_checkpoint |- log->log_start | |- log->last_cp_seq |- log->next_checkpoint |- log->seq=n |- log->seq=10+n At the same time, if there is no data-only stripes, this scene may appear, | meta1 | meta2 | meta3 | meta 1 is valid, meta 2 is invalid. meta 3 could be valid. so we should The solution is we create a new meta in meta2 with its seq == meta1's seq + 10 and let superblock points to meta2. Signed-off-by: JackieLiu <liuyun01@kylinos.cn> Reviewed-by: Zhengyuan Liu <liuzhengyuan@kylinos.cn> Reviewed-by: Song Liu <songliubraving@fb.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:
parent
f687a33ef0
commit
43b9674832
|
@ -2077,7 +2077,6 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctx->seq += 10;
|
||||
list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) {
|
||||
struct r5l_meta_block *mb;
|
||||
int i;
|
||||
|
@ -2137,6 +2136,8 @@ 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;
|
||||
struct stripe_head *sh;
|
||||
|
||||
ctx.pos = log->last_checkpoint;
|
||||
ctx.seq = log->last_cp_seq;
|
||||
|
@ -2154,6 +2155,18 @@ static int r5l_recovery_log(struct r5l_log *log)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
pos = ctx.pos;
|
||||
ctx.seq += 10;
|
||||
|
||||
if (ctx.data_only_stripes == 0) {
|
||||
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))
|
||||
pr_debug("md/raid:%s: starting from clean shutdown\n",
|
||||
mdname(mddev));
|
||||
|
@ -2171,10 +2184,9 @@ static int r5l_recovery_log(struct r5l_log *log)
|
|||
}
|
||||
|
||||
log->log_start = ctx.pos;
|
||||
log->next_checkpoint = ctx.pos;
|
||||
log->seq = ctx.seq;
|
||||
r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq);
|
||||
r5l_write_super(log, ctx.pos);
|
||||
log->last_checkpoint = pos;
|
||||
r5l_write_super(log, pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue