diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid5-cache.c | 18 | ||||
-rw-r--r-- | drivers/md/raid5.c | 11 | ||||
-rw-r--r-- | drivers/md/raid5.h | 1 |
3 files changed, 28 insertions, 2 deletions
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 6479f15a5434..ea1480392eba 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -507,6 +507,24 @@ void r5l_write_stripe_run(struct r5l_log *log) mutex_unlock(&log->io_mutex); } +int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio) +{ + if (!log) + return -ENODEV; + /* + * we flush log disk cache first, then write stripe data to raid disks. + * So if bio is finished, the log disk cache is flushed already. The + * recovery guarantees we can recovery the bio from log disk, so we + * don't need to flush again + */ + if (bio->bi_iter.bi_size == 0) { + bio_endio(bio); + return 0; + } + bio->bi_rw &= ~REQ_FLUSH; + return -EAGAIN; +} + /* This will run after log space is reclaimed */ static void r5l_run_no_space_stripes(struct r5l_log *log) { diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 46042c7c25a5..a622ccb3477a 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5146,8 +5146,15 @@ static void make_request(struct mddev *mddev, struct bio * bi) bool do_prepare; if (unlikely(bi->bi_rw & REQ_FLUSH)) { - md_flush_request(mddev, bi); - return; + int ret = r5l_handle_flush_request(conf->log, bi); + + if (ret == 0) + return; + if (ret == -ENODEV) { + md_flush_request(mddev, bi); + return; + } + /* ret == -EAGAIN, fallback */ } md_write_start(mddev, bi); diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 1f16d437bfda..32c8ce81248b 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h @@ -629,4 +629,5 @@ extern int r5l_write_stripe(struct r5l_log *log, struct stripe_head *head_sh); extern void r5l_write_stripe_run(struct r5l_log *log); extern void r5l_flush_stripe_to_raid(struct r5l_log *log); extern void r5l_stripe_write_finished(struct stripe_head *sh); +extern int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio); #endif |