]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc: ObjectCacher flusher might needs additional locks
authorJason Dillaman <dillaman@redhat.com>
Thu, 7 May 2015 18:06:16 +0000 (14:06 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 4 Jun 2015 20:52:05 +0000 (16:52 -0400)
librbd requires the ObjectCacher flusher thread to acquire
an additional lock in order to maintain lock ordering
constraints.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/LibrbdWriteback.cc
src/librbd/LibrbdWriteback.h
src/osdc/ObjectCacher.cc
src/osdc/WritebackHandler.h

index cd2e1de2aa8a66bc2d5a0c2d923d0fe386178412..058760e6d97994b28fa7383f4d0437c6e85fe706 100644 (file)
@@ -157,6 +157,7 @@ namespace librbd {
                               uint64_t trunc_size, __u32 trunc_seq,
                               Context *oncommit)
   {
+    assert(m_ictx->owner_lock.is_locked());
     uint64_t object_no = oid_to_object_no(oid.name, m_ictx->object_prefix);
     
     write_result_d *result = new write_result_d(oid.name, oncommit);
@@ -169,6 +170,14 @@ namespace librbd {
     return ++m_tid;
   }
 
+  void LibrbdWriteback::get_client_lock() {
+    m_ictx->owner_lock.get_read();
+  }
+
+  void LibrbdWriteback::put_client_lock() {
+    m_ictx->owner_lock.put_read();
+  }
+
   void LibrbdWriteback::complete_writes(const std::string& oid)
   {
     assert(m_lock.is_locked());
index 2c71e8434cb9d25aba1e734a23625f4d6e0aed8f..b5578ae62f5c3e92718639ec8aa4eb0a09b4d1c8 100644 (file)
@@ -38,6 +38,9 @@ namespace librbd {
                        const bufferlist &bl, utime_t mtime, uint64_t trunc_size,
                        __u32 trunc_seq, Context *oncommit);
 
+    virtual void get_client_lock();
+    virtual void put_client_lock();
+
     struct write_result_d {
       bool done;
       int ret;
index 5465706370fcd7b9a8c46c3367c77fbbf618c681..db6779c7dbf0ce8566cd7c98e5a15f93357e38a5 100644 (file)
@@ -1520,6 +1520,7 @@ int ObjectCacher::_wait_for_write(OSDWrite *wr, uint64_t len, ObjectSet *oset, C
 void ObjectCacher::flusher_entry()
 {
   ldout(cct, 10) << "flusher start" << dendl;
+  writeback_handler.get_client_lock();
   lock.Lock();
   while (!flusher_stop) {
     loff_t all = get_stat_tx() + get_stat_rx() + get_stat_clean() + get_stat_dirty();
@@ -1556,13 +1557,21 @@ void ObjectCacher::flusher_entry()
       if (!max) {
        // back off the lock to avoid starving other threads
        lock.Unlock();
+        writeback_handler.put_client_lock();
+        writeback_handler.get_client_lock();
        lock.Lock();
        continue;
       }
     }
     if (flusher_stop)
       break;
+
+    writeback_handler.put_client_lock();
     flusher_cond.WaitInterval(cct, lock, utime_t(1,0));
+    lock.Unlock();
+
+    writeback_handler.get_client_lock();
+    lock.Lock();
   }
 
   /* Wait for reads to finish. This is only possible if handling
@@ -1578,6 +1587,7 @@ void ObjectCacher::flusher_entry()
   }
 
   lock.Unlock();
+  writeback_handler.put_client_lock();
   ldout(cct, 10) << "flusher finish" << dendl;
 }
 
index 466f84e77983bfed4cef8e7d8c12bfd1f0ab2cd0..fe7d977de26e2f0c76585914f2c867d890336777 100644 (file)
@@ -37,6 +37,9 @@ class WritebackHandler {
                          int op, int flags, Context *onack, Context *oncommit) {
     assert(0 == "this WritebackHandler does not support the lock operation");
   }
+
+  virtual void get_client_lock() {}
+  virtual void put_client_lock() {}
 };
 
 #endif