From: Yan, Zheng Date: Mon, 29 Jan 2018 02:59:00 +0000 (+0800) Subject: osdc/Journaler: make sure flush() writes enough data X-Git-Tag: v12.2.5~40^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7184232070980cbeb042206bdc9f6ecb8d99abae;p=ceph.git osdc/Journaler: make sure flush() writes enough data If _do_flush() fails to write all data because of prezere, _do_flush() should be called again when prezero finishes. Otherwise flush waiters may sleep forever. Fixes: http://tracker.ceph.com/issues/22824 Signed-off-by: "Yan, Zheng" (cherry picked from commit 94a2076b9de9e8ffb73f3d5c873bdb87a0429e65) --- diff --git a/src/osdc/Journaler.cc b/src/osdc/Journaler.cc index 4217ab91ea1f..94386101a1d3 100644 --- a/src/osdc/Journaler.cc +++ b/src/osdc/Journaler.cc @@ -633,19 +633,16 @@ void Journaler::_do_flush(unsigned amount) ldout(cct, 10) << "_do_flush wanted to do " << flush_pos << "~" << len << " already too close to prezero_pos " << prezero_pos << ", zeroing first" << dendl; - waiting_for_zero = true; + waiting_for_zero_pos = flush_pos + len; return; } if (static_cast(newlen) < len) { ldout(cct, 10) << "_do_flush wanted to do " << flush_pos << "~" << len << " but hit prezero_pos " << prezero_pos << ", will do " << flush_pos << "~" << newlen << dendl; + waiting_for_zero_pos = flush_pos + len; len = newlen; - } else { - waiting_for_zero = false; } - } else { - waiting_for_zero = false; } ldout(cct, 10) << "_do_flush flushing " << flush_pos << "~" << len << dendl; @@ -853,8 +850,8 @@ void Journaler::_finish_prezero(int r, uint64_t start, uint64_t len) pending_zero.erase(b); } - if (waiting_for_zero) { - _do_flush(); + if (waiting_for_zero_pos > flush_pos) { + _do_flush(waiting_for_zero_pos - flush_pos); } } else { pending_zero.insert(start, len); diff --git a/src/osdc/Journaler.h b/src/osdc/Journaler.h index 1c3028045e7f..d65419a652be 100644 --- a/src/osdc/Journaler.h +++ b/src/osdc/Journaler.h @@ -310,7 +310,7 @@ private: // protect write_buf from bufferlist _len overflow Throttle write_buf_throttle; - bool waiting_for_zero; + uint64_t waiting_for_zero_pos; interval_set pending_zero; // non-contig bits we've zeroed std::map pending_safe; // flush_pos -> safe_pos // when safe through given offset @@ -407,7 +407,7 @@ public: prezeroing_pos(0), prezero_pos(0), write_pos(0), flush_pos(0), safe_pos(0), next_safe_pos(0), write_buf_throttle(cct, "write_buf_throttle", UINT_MAX - (UINT_MAX >> 3)), - waiting_for_zero(false), + waiting_for_zero_pos(0), read_pos(0), requested_pos(0), received_pos(0), fetch_len(0), temp_fetch_len(0), on_readable(0), on_write_error(NULL), called_write_error(false), @@ -444,7 +444,7 @@ public: expire_pos = 0; trimming_pos = 0; trimmed_pos = 0; - waiting_for_zero = false; + waiting_for_zero_pos = 0; } // Asynchronous operations