]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc/ObjectCacher: overwrite might cause stray read request callbacks 37813/head
authorJason Dillaman <dillaman@redhat.com>
Mon, 21 Sep 2020 16:53:37 +0000 (12:53 -0400)
committerNathan Cutler <ncutler@suse.com>
Mon, 26 Oct 2020 20:30:29 +0000 (21:30 +0100)
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 <dillaman@redhat.com>
(cherry picked from commit 94d43165ed7319d163640f38d154f8f80408eb14)

src/osdc/ObjectCacher.cc

index b64d9abf2e113bf2c5a04cc52aebf94962784e24..9aaf2baffee46f15337d840176a05b5d0a0102d8 100644 (file)
@@ -1719,6 +1719,7 @@ int ObjectCacher::writex(OSDWrite *wr, ObjectSet *oset, Context *onfreespace,
     trace.event("start");
   }
 
+  list<Context*> wait_for_reads;
   for (vector<ObjectExtent>::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;