diff options
author | JackieLiu <liuyun01@kylinos.cn> | 2016-12-04 22:58:53 -0500 |
---|---|---|
committer | Shaohua Li <shli@fb.com> | 2016-12-05 20:11:02 -0500 |
commit | 43b9674832cc41ad0ad7b7e2ec397e47dcd5f6c3 (patch) | |
tree | 0bce93ce3f2cf58db16454a7d68d4ced1fd6f47f | |
parent | f687a33ef02d3e0f13c4fa9e3b2e90f656bbfb26 (diff) |
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>
-rw-r--r-- | drivers/md/raid5-cache.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index c36f86b47252..5efb876a588d 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c | |||
@@ -2077,7 +2077,6 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log, | |||
2077 | return -ENOMEM; | 2077 | return -ENOMEM; |
2078 | } | 2078 | } |
2079 | 2079 | ||
2080 | ctx->seq += 10; | ||
2081 | list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) { | 2080 | list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) { |
2082 | struct r5l_meta_block *mb; | 2081 | struct r5l_meta_block *mb; |
2083 | int i; | 2082 | int i; |
@@ -2137,6 +2136,8 @@ static int r5l_recovery_log(struct r5l_log *log) | |||
2137 | struct mddev *mddev = log->rdev->mddev; | 2136 | struct mddev *mddev = log->rdev->mddev; |
2138 | struct r5l_recovery_ctx ctx; | 2137 | struct r5l_recovery_ctx ctx; |
2139 | int ret; | 2138 | int ret; |
2139 | sector_t pos; | ||
2140 | struct stripe_head *sh; | ||
2140 | 2141 | ||
2141 | ctx.pos = log->last_checkpoint; | 2142 | ctx.pos = log->last_checkpoint; |
2142 | ctx.seq = log->last_cp_seq; | 2143 | ctx.seq = log->last_cp_seq; |
@@ -2154,6 +2155,18 @@ static int r5l_recovery_log(struct r5l_log *log) | |||
2154 | if (ret) | 2155 | if (ret) |
2155 | return ret; | 2156 | return ret; |
2156 | 2157 | ||
2158 | pos = ctx.pos; | ||
2159 | ctx.seq += 10; | ||
2160 | |||
2161 | if (ctx.data_only_stripes == 0) { | ||
2162 | log->next_checkpoint = ctx.pos; | ||
2163 | r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq++); | ||
2164 | ctx.pos = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS); | ||
2165 | } else { | ||
2166 | sh = list_last_entry(&ctx.cached_list, struct stripe_head, lru); | ||
2167 | log->next_checkpoint = sh->log_start; | ||
2168 | } | ||
2169 | |||
2157 | if ((ctx.data_only_stripes == 0) && (ctx.data_parity_stripes == 0)) | 2170 | if ((ctx.data_only_stripes == 0) && (ctx.data_parity_stripes == 0)) |
2158 | pr_debug("md/raid:%s: starting from clean shutdown\n", | 2171 | pr_debug("md/raid:%s: starting from clean shutdown\n", |
2159 | mdname(mddev)); | 2172 | mdname(mddev)); |
@@ -2171,10 +2184,9 @@ static int r5l_recovery_log(struct r5l_log *log) | |||
2171 | } | 2184 | } |
2172 | 2185 | ||
2173 | log->log_start = ctx.pos; | 2186 | log->log_start = ctx.pos; |
2174 | log->next_checkpoint = ctx.pos; | ||
2175 | log->seq = ctx.seq; | 2187 | log->seq = ctx.seq; |
2176 | r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq); | 2188 | log->last_checkpoint = pos; |
2177 | r5l_write_super(log, ctx.pos); | 2189 | r5l_write_super(log, pos); |
2178 | return 0; | 2190 | return 0; |
2179 | } | 2191 | } |
2180 | 2192 | ||