]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc/Filer: use finisher to execute C_Probe and C_PurgeRange 3159/head
authorYan, Zheng <zyan@redhat.com>
Thu, 4 Dec 2014 04:18:47 +0000 (12:18 +0800)
committerJohn Spray <jspray@redhat.com>
Thu, 11 Dec 2014 22:49:09 +0000 (22:49 +0000)
Currently contexts C_Probe/C_PurgeRange are executed while holding
OSDSession::completion_lock. C_Probe and C_PurgeRange may call
Objecter::stat() and Objecter::remove() respectively, which acquire
Objecter::rwlock. This can cause deadlock because there is intermediate
dependency between Objecter::rwlock and OSDSession::completion_lock:

 Objecter::rwlock -> OSDSession::lock -> OSDSession::completion_lock

The fix is exexcute C_Probe/C_PurgeRange in finisher thread.

Fixes: #10229
Signed-off-by: Yan, Zheng <zyan@redhat.com>
(cherry picked from commit d3ee89ace660161df7796affbf9a70f3d0dedce1)

src/client/Client.cc
src/mds/MDS.cc
src/osdc/Filer.cc
src/osdc/Filer.h
src/osdc/Journaler.h
src/tools/cephfs/Dumper.cc

index 1d011ad1aae8e6bb1f221d348fd4ad53b5f84b29..eb183a34fff67fc973e721256e4da4bd97b0a4b4 100644 (file)
@@ -212,7 +212,7 @@ Client::Client(Messenger *m, MonClient *mc)
                                  cct->_conf->client_oc_max_dirty_age,
                                  true);
   objecter_finisher.start();
-  filer = new Filer(objecter);
+  filer = new Filer(objecter, &objecter_finisher);
 }
 
 
index 5661fb51dc043deb407f190cd0b1d5f301292b56..229be733a0759a461dcd205a2c76b6e44c4fe562 100644 (file)
@@ -126,7 +126,7 @@ MDS::MDS(const std::string &n, Messenger *m, MonClient *mc) :
   objecter = new Objecter(m->cct, messenger, monc, 0, 0);
   objecter->unset_honor_osdmap_full();
 
-  filer = new Filer(objecter);
+  filer = new Filer(objecter, &finisher);
 
   mdcache = new MDCache(this);
   mdlog = new MDLog(this);
index 84392de53b59a877b1a2f48ebe5242314cb32f8a..d89c8781ea0f0f614fbcca79dc2d2dd5ea013db6 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "include/Context.h"
 
+#include "common/Finisher.h"
 #include "common/config.h"
 
 #define dout_subsys ceph_subsys_filer
@@ -134,8 +135,9 @@ void Filer::_probe(Probe *probe)
   for (std::vector<ObjectExtent>::iterator i = stat_extents.begin();
       i != stat_extents.end(); ++i) {
     C_Probe *c = new C_Probe(this, probe, i->oid);
-    objecter->stat(i->oid, i->oloc, probe->snapid, &c->size, &c->mtime, 
-                   probe->flags | CEPH_OSD_FLAG_RWORDERED, c);
+    objecter->stat(i->oid, i->oloc, probe->snapid, &c->size, &c->mtime,
+                  probe->flags | CEPH_OSD_FLAG_RWORDERED,
+                  new C_OnFinisher(c, finisher));
   }
 }
 
@@ -339,8 +341,8 @@ void Filer::_do_purge_range(PurgeRange *pr, int fin)
     const OSDMap *osdmap = objecter->get_osdmap_read();
     const object_locator_t oloc = osdmap->file_to_object_locator(pr->layout);
     objecter->put_osdmap_read();
-    objecter->remove(oid, oloc, pr->snapc, pr->mtime, pr->flags,
-                    NULL, new C_PurgeRange(this, pr));
+    objecter->remove(oid, oloc, pr->snapc, pr->mtime, pr->flags, NULL,
+                    new C_OnFinisher(new C_PurgeRange(this, pr), finisher));
   }
 }
 
index 1164d95873a04477ff33ff64ce2c26705c09e630..cbf3fa25a914df939ddf674a3e7de748fedb59d7 100644 (file)
@@ -35,7 +35,7 @@
 class Context;
 class Messenger;
 class OSDMap;
-
+class Finisher;
 
 
 /**** Filer interface ***/
@@ -43,6 +43,7 @@ class OSDMap;
 class Filer {
   CephContext *cct;
   Objecter   *objecter;
+  Finisher   *finisher;
   
   // probes
   struct Probe {
@@ -88,7 +89,7 @@ class Filer {
   Filer(const Filer& other);
   const Filer operator=(const Filer& other);
 
-  Filer(Objecter *o) : cct(o->cct), objecter(o) {}
+  Filer(Objecter *o, Finisher *f) : cct(o->cct), objecter(o), finisher(f) {}
   ~Filer() {}
 
   bool is_active() {
index d171c263663ce0ce099176fbd9f2d64dc4ee70c1..c4e9b2fbd8b0d4d75a26048e85698f03083dd4c5 100644 (file)
@@ -377,7 +377,7 @@ public:
     ino(ino_), pg_pool(pool), readonly(true),
     stream_format(-1), journal_stream(-1),
     magic(mag),
-    objecter(obj), filer(objecter), logger(l), logger_key_lat(lkey),
+    objecter(obj), filer(objecter, f), logger(l), logger_key_lat(lkey),
     timer(tim), delay_flush_event(0),
     state(STATE_UNDEF), error(0),
     prezeroing_pos(0), prezero_pos(0), write_pos(0), flush_pos(0), safe_pos(0),
index 8ee3cdc0b4358a371bbed8b9410c5c2577d0a832..f6631e262a67c4a629fc8f439753516c90f34daa 100644 (file)
@@ -85,7 +85,7 @@ void Dumper::dump(const char *dump_file)
 
   cout << "journal is " << start << "~" << len << std::endl;
 
-  Filer filer(objecter);
+  Filer filer(objecter, &finisher);
   bufferlist bl;
 
   C_SaferCond cond;
@@ -188,7 +188,7 @@ void Dumper::undump(const char *dump_file)
     return;
   }
 
-  Filer filer(objecter);
+  Filer filer(objecter, &finisher);
 
   /* Erase any objects at the end of the region to which we shall write
    * the new log data.  This is to avoid leaving trailing junk after