From ba0afa5d2e4817ffbe3c61eacad0678c22740d5b Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Mon, 21 Sep 2020 12:53:37 -0400 Subject: [PATCH] osdc/ObjectCacher: overwrite might cause stray read request callbacks In librbd, if readahead is active, there might be a pending read request for the cache which is then (partially) overwritten by a write request. This overwrite will cause bh splits and merges which can cause the bh read callback to fail to invoke the pending read callbacks. Fixes: https://tracker.ceph.com/issues/46822 Signed-off-by: Jason Dillaman (cherry picked from commit 94d43165ed7319d163640f38d154f8f80408eb14) --- src/osdc/ObjectCacher.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index b64d9abf2e113..9aaf2baffee46 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -1719,6 +1719,7 @@ int ObjectCacher::writex(OSDWrite *wr, ObjectSet *oset, Context *onfreespace, trace.event("start"); } + list wait_for_reads; for (vector::iterator ex_it = wr->extents.begin(); ex_it != wr->extents.end(); ++ex_it) { @@ -1732,6 +1733,12 @@ int ObjectCacher::writex(OSDWrite *wr, ObjectSet *oset, Context *onfreespace, bool missing = bh->is_missing(); bh->snapc = wr->snapc; + // readers that need to be woken up due to an overwrite + for (auto& [_, wait_for_read] : bh->waitfor_read) { + wait_for_reads.splice(wait_for_reads.end(), wait_for_read); + } + bh->waitfor_read.clear(); + bytes_written += ex_it->length; if (bh->is_tx()) { bytes_written_in_flush += ex_it->length; @@ -1791,6 +1798,8 @@ int ObjectCacher::writex(OSDWrite *wr, ObjectSet *oset, Context *onfreespace, int r = _wait_for_write(wr, bytes_written, oset, &trace, onfreespace); delete wr; + finish_contexts(cct, wait_for_reads, 0); + //verify_stats(); trim(); return r; -- 2.39.5