提交 5ddf0440 编写于 作者: S Song Liu 提交者: Shaohua Li

md/r5cache: handle sync with data in write back cache

Currently, sync of raid456 array cannot make progress when hitting
data in writeback r5cache.

This patch fixes this issue by flushing cached data of the stripe
before processing the sync request. This is achived by:

1. In handle_stripe(), do not set STRIPE_SYNCING if the stripe is
   in write back cache;
2. In r5c_try_caching_write(), handle the stripe in sync with write
   through;
3. In do_release_stripe(), make stripe in sync write out and send
   it to the state machine.

Shaohua: explictly set STRIPE_HANDLE after write out completed
Signed-off-by: NSong Liu <songliubraving@fb.com>
Signed-off-by: NShaohua Li <shli@fb.com>
上级 70d466f7
...@@ -2637,8 +2637,11 @@ int r5c_try_caching_write(struct r5conf *conf, ...@@ -2637,8 +2637,11 @@ int r5c_try_caching_write(struct r5conf *conf,
* When run in degraded mode, array is set to write-through mode. * When run in degraded mode, array is set to write-through mode.
* This check helps drain pending write safely in the transition to * This check helps drain pending write safely in the transition to
* write-through mode. * write-through mode.
*
* When a stripe is syncing, the write is also handled in write
* through mode.
*/ */
if (s->failed) { if (s->failed || test_bit(STRIPE_SYNCING, &sh->state)) {
r5c_make_stripe_write_out(sh); r5c_make_stripe_write_out(sh);
return -EAGAIN; return -EAGAIN;
} }
...@@ -2841,6 +2844,9 @@ void r5c_finish_stripe_write_out(struct r5conf *conf, ...@@ -2841,6 +2844,9 @@ void r5c_finish_stripe_write_out(struct r5conf *conf,
} }
r5l_append_flush_payload(log, sh->sector); r5l_append_flush_payload(log, sh->sector);
/* stripe is flused to raid disks, we can do resync now */
if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state))
set_bit(STRIPE_HANDLE, &sh->state);
} }
int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh) int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh)
......
...@@ -233,11 +233,15 @@ static void do_release_stripe(struct r5conf *conf, struct stripe_head *sh, ...@@ -233,11 +233,15 @@ static void do_release_stripe(struct r5conf *conf, struct stripe_head *sh,
if (test_bit(R5_InJournal, &sh->dev[i].flags)) if (test_bit(R5_InJournal, &sh->dev[i].flags))
injournal++; injournal++;
/* /*
* When quiesce in r5c write back, set STRIPE_HANDLE for stripes with * In the following cases, the stripe cannot be released to cached
* data in journal, so they are not released to cached lists * lists. Therefore, we make the stripe write out and set
* STRIPE_HANDLE:
* 1. when quiesce in r5c write back;
* 2. when resync is requested fot the stripe.
*/ */
if (conf->quiesce && r5c_is_writeback(conf->log) && if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) ||
!test_bit(STRIPE_HANDLE, &sh->state) && injournal != 0) { (conf->quiesce && r5c_is_writeback(conf->log) &&
!test_bit(STRIPE_HANDLE, &sh->state) && injournal != 0)) {
if (test_bit(STRIPE_R5C_CACHING, &sh->state)) if (test_bit(STRIPE_R5C_CACHING, &sh->state))
r5c_make_stripe_write_out(sh); r5c_make_stripe_write_out(sh);
set_bit(STRIPE_HANDLE, &sh->state); set_bit(STRIPE_HANDLE, &sh->state);
...@@ -4656,8 +4660,13 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -4656,8 +4660,13 @@ static void handle_stripe(struct stripe_head *sh)
if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) && !sh->batch_head) { if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) && !sh->batch_head) {
spin_lock(&sh->stripe_lock); spin_lock(&sh->stripe_lock);
/* Cannot process 'sync' concurrently with 'discard' */ /*
if (!test_bit(STRIPE_DISCARD, &sh->state) && * Cannot process 'sync' concurrently with 'discard'.
* Flush data in r5cache before 'sync'.
*/
if (!test_bit(STRIPE_R5C_PARTIAL_STRIPE, &sh->state) &&
!test_bit(STRIPE_R5C_FULL_STRIPE, &sh->state) &&
!test_bit(STRIPE_DISCARD, &sh->state) &&
test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
set_bit(STRIPE_SYNCING, &sh->state); set_bit(STRIPE_SYNCING, &sh->state);
clear_bit(STRIPE_INSYNC, &sh->state); clear_bit(STRIPE_INSYNC, &sh->state);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册