]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
journal: possible race condition during fetch playback
authorJason Dillaman <dillaman@redhat.com>
Tue, 8 Mar 2016 15:48:24 +0000 (10:48 -0500)
committerJason Dillaman <dillaman@redhat.com>
Tue, 8 Mar 2016 16:01:33 +0000 (11:01 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/journal/JournalPlayer.cc
src/journal/JournalPlayer.h
src/journal/ObjectPlayer.h

index e001c018c6e359ede7f8926708f593dad6387871..b05fead55a8c9ed01269a4086ecebb0f5c783d79 100644 (file)
@@ -81,6 +81,10 @@ JournalPlayer::JournalPlayer(librados::IoCtx &ioctx,
 
 JournalPlayer::~JournalPlayer() {
   m_async_op_tracker.wait_for_ops();
+  {
+    Mutex::Locker locker(m_lock);
+    assert(m_fetch_object_numbers.empty());
+  }
   m_replay_handler->put();
 }
 
@@ -253,7 +257,8 @@ int JournalPlayer::process_prefetch(uint64_t object_number) {
   ObjectPlayers &object_players = m_object_players[splay_offset];
 
   // prefetch in-order since a newer splay object could prefetch first
-  while (!object_players.begin()->second->is_fetch_in_progress()) {
+  while (m_fetch_object_numbers.count(
+           object_players.begin()->second->get_object_number()) == 0) {
     ObjectPlayerPtr object_player = object_players.begin()->second;
     uint64_t player_object_number = object_player->get_object_number();
 
@@ -361,14 +366,9 @@ int JournalPlayer::process_playback(uint64_t object_number) {
 
 bool JournalPlayer::is_object_set_ready() const {
   assert(m_lock.is_locked());
-  if (m_watch_scheduled) {
+  if (m_watch_scheduled || !m_fetch_object_numbers.empty()) {
     return false;
   }
-  for (auto &players : m_object_players) {
-    if (players.second.begin()->second->is_fetch_in_progress()) {
-      return false;
-    }
-  }
   return true;
 }
 
@@ -476,6 +476,9 @@ void JournalPlayer::fetch(uint64_t object_num) {
 
   std::string oid = utils::get_object_name(m_object_oid_prefix, object_num);
 
+  assert(m_fetch_object_numbers.count(object_num) == 0);
+  m_fetch_object_numbers.insert(object_num);
+
   ldout(m_cct, 10) << __func__ << ": " << oid << dendl;
   C_Fetch *fetch_ctx = new C_Fetch(this, object_num);
   ObjectPlayerPtr object_player(new ObjectPlayer(
@@ -493,6 +496,9 @@ void JournalPlayer::handle_fetched(uint64_t object_num, int r) {
                    << ": r=" << r << dendl;
 
   Mutex::Locker locker(m_lock);
+  assert(m_fetch_object_numbers.count(object_num) == 1);
+  m_fetch_object_numbers.erase(object_num);
+
   if (r == -ENOENT) {
     r = 0;
   }
index 007a4a160b59746d092d10e3bec7013055b94fcc..902a1959d95b045975d1b388eaa4ab6c352d662e 100644 (file)
@@ -45,6 +45,7 @@ private:
   typedef std::map<uint64_t, ObjectPlayerPtr> ObjectPlayers;
   typedef std::map<uint8_t, ObjectPlayers> SplayedObjectPlayers;
   typedef std::map<uint8_t, ObjectPosition> SplayedObjectPositions;
+  typedef std::set<uint64_t> ObjectNumbers;
 
   enum State {
     STATE_INIT,
@@ -114,6 +115,8 @@ private:
 
   bool m_handler_notified = false;
 
+  ObjectNumbers m_fetch_object_numbers;
+
   PrefetchSplayOffsets m_prefetch_splay_offsets;
   SplayedObjectPlayers m_object_players;
   uint64_t m_commit_object;
index c63e2f7a2527ae09f0a149bdc1c1b969d6642826..f68ee3741d8277fc02d4854fef476d2f442d4a29 100644 (file)
@@ -46,11 +46,6 @@ public:
   void watch(Context *on_fetch, double interval);
   void unwatch();
 
-  inline bool is_fetch_in_progress() const {
-    Mutex::Locker locker(m_lock);
-    return m_fetch_in_progress;
-  }
-
   void front(Entry *entry) const;
   void pop_front();
   inline bool empty() const {