From 335261869d33a9985965f5718063278673eabeee Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 23 Oct 2013 15:26:28 +0100 Subject: [PATCH] mirror: Don't count bytes transferred for the purposes of keeping the stream empty as part of our bwlimit This prevents a fairly nasty situation occurring where the rate of change on the disc is high enough that just servicing it generates enough traffic to keep us over the bwlimit threshold indefinitely. That would cause us to sleep during the only windows we'd ordinarily have to advance the offset. --- src/mirror.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mirror.c b/src/mirror.c index e17c536..dbf34c7 100644 --- a/src/mirror.c +++ b/src/mirror.c @@ -357,7 +357,7 @@ int mirror_setup_next_xfer( struct mirror_ctrl *ctrl ) * full, and stop when it's a quarter full. This stops a busy client from * stalling a migration forever. FIXME: made-up numbers. */ - if ( bitset_stream_size( serve->allocation_map ) > BITSET_STREAM_SIZE / 2 ) { + if ( mirror->offset < serve->size && bitset_stream_size( serve->allocation_map ) > BITSET_STREAM_SIZE / 2 ) { ctrl->clear_events = 1; } @@ -572,10 +572,17 @@ static void mirror_read_cb( struct ev_loop *loop, ev_io *w, int revents ) /* transfer was completed, so now we need to either set up the next * transfer of this pass, set up the first transfer of the next pass, or * complete the migration */ - m->all_dirty += xfer->len; xfer->read = 0; xfer->written = 0; + /* We don't account for bytes written in this mode, to stop high-throughput + * discs getting stuck in "drain the event queue!" mode forever + */ + if ( !ctrl->clear_events ) { + m->all_dirty += xfer->len; + } + + /* This next bit could take a little while, which is fine */ ev_timer_stop( ctrl->ev_loop, &ctrl->timeout_watcher );