diff options
author | Song Liu <songliubraving@fb.com> | 2017-05-11 17:03:44 -0700 |
---|---|---|
committer | Shaohua Li <shli@fb.com> | 2017-05-11 22:14:40 -0700 |
commit | 5ddf0440a1a28f00f69ed2e093476bab3b60c2c3 (patch) | |
tree | 33a11155215f93288b40d300839a58f3c13b7f8c /drivers/md/raid5-cache.c | |
parent | 70d466f760b351fe30b5f8c956354ddf29aa676b (diff) | |
download | linux-stable-5ddf0440a1a28f00f69ed2e093476bab3b60c2c3.tar.gz linux-stable-5ddf0440a1a28f00f69ed2e093476bab3b60c2c3.tar.bz2 linux-stable-5ddf0440a1a28f00f69ed2e093476bab3b60c2c3.zip |
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: Song Liu <songliubraving@fb.com>
Signed-off-by: Shaohua Li <shli@fb.com>
Diffstat (limited to 'drivers/md/raid5-cache.c')
-rw-r--r-- | drivers/md/raid5-cache.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index cc3f8442f11f..4c00bc248287 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -2637,8 +2637,11 @@ int r5c_try_caching_write(struct r5conf *conf, * When run in degraded mode, array is set to write-through mode. * This check helps drain pending write safely in the transition to * 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); return -EAGAIN; } @@ -2841,6 +2844,9 @@ void r5c_finish_stripe_write_out(struct r5conf *conf, } 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) |