Skip to content

Commit ea17481

Browse files
liu-song-6shligit
authored andcommitted
md/r5cache: generate R5LOG_PAYLOAD_FLUSH
In r5c_finish_stripe_write_out(), R5LOG_PAYLOAD_FLUSH is append to log->current_io. Appending R5LOG_PAYLOAD_FLUSH in quiesce needs extra writes to journal. To simplify the logic, we just skip R5LOG_PAYLOAD_FLUSH in quiesce. Even R5LOG_PAYLOAD_FLUSH supports multiple stripes per payload. However, current implementation is one stripe per R5LOG_PAYLOAD_FLUSH, which is simpler. Signed-off-by: Song Liu <[email protected]> Signed-off-by: Shaohua Li <[email protected]>
1 parent 2d4f468 commit ea17481

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

drivers/md/raid5-cache.c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ static void r5l_log_endio(struct bio *bio)
593593

594594
spin_lock_irqsave(&log->io_list_lock, flags);
595595
__r5l_set_io_unit_state(io, IO_UNIT_IO_END);
596-
if (log->need_cache_flush)
596+
if (log->need_cache_flush && !list_empty(&io->stripe_list))
597597
r5l_move_to_end_ios(log);
598598
else
599599
r5l_log_run_stripes(log);
@@ -621,9 +621,11 @@ static void r5l_log_endio(struct bio *bio)
621621
bio_endio(bi);
622622
atomic_dec(&io->pending_stripe);
623623
}
624-
if (atomic_read(&io->pending_stripe) == 0)
625-
__r5l_stripe_write_finished(io);
626624
}
625+
626+
/* finish flush only io_unit and PAYLOAD_FLUSH only io_unit */
627+
if (atomic_read(&io->pending_stripe) == 0)
628+
__r5l_stripe_write_finished(io);
627629
}
628630

629631
static void r5l_do_submit_io(struct r5l_log *log, struct r5l_io_unit *io)
@@ -845,6 +847,41 @@ static void r5l_append_payload_page(struct r5l_log *log, struct page *page)
845847
r5_reserve_log_entry(log, io);
846848
}
847849

850+
static void r5l_append_flush_payload(struct r5l_log *log, sector_t sect)
851+
{
852+
struct mddev *mddev = log->rdev->mddev;
853+
struct r5conf *conf = mddev->private;
854+
struct r5l_io_unit *io;
855+
struct r5l_payload_flush *payload;
856+
int meta_size;
857+
858+
/*
859+
* payload_flush requires extra writes to the journal.
860+
* To avoid handling the extra IO in quiesce, just skip
861+
* flush_payload
862+
*/
863+
if (conf->quiesce)
864+
return;
865+
866+
mutex_lock(&log->io_mutex);
867+
meta_size = sizeof(struct r5l_payload_flush) + sizeof(__le64);
868+
869+
if (r5l_get_meta(log, meta_size)) {
870+
mutex_unlock(&log->io_mutex);
871+
return;
872+
}
873+
874+
/* current implementation is one stripe per flush payload */
875+
io = log->current_io;
876+
payload = page_address(io->meta_page) + io->meta_offset;
877+
payload->header.type = cpu_to_le16(R5LOG_PAYLOAD_FLUSH);
878+
payload->header.flags = cpu_to_le16(0);
879+
payload->size = cpu_to_le32(sizeof(__le64));
880+
payload->flush_stripes[0] = cpu_to_le64(sect);
881+
io->meta_offset += meta_size;
882+
mutex_unlock(&log->io_mutex);
883+
}
884+
848885
static int r5l_log_stripe(struct r5l_log *log, struct stripe_head *sh,
849886
int data_pages, int parity_pages)
850887
{
@@ -2784,6 +2821,8 @@ void r5c_finish_stripe_write_out(struct r5conf *conf,
27842821
atomic_dec(&conf->r5c_flushing_full_stripes);
27852822
atomic_dec(&conf->r5c_cached_full_stripes);
27862823
}
2824+
2825+
r5l_append_flush_payload(log, sh->sector);
27872826
}
27882827

27892828
int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh)

0 commit comments

Comments
 (0)