]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/ObjectStore: properly clone object map when replaying OP_COLL_MOVE_RENAME 11388/head
authorYan, Zheng <zyan@redhat.com>
Mon, 10 Oct 2016 14:17:28 +0000 (22:17 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 13 Oct 2016 08:27:22 +0000 (16:27 +0800)
FileStore::_close_replay_guard does not sync the object map. If OSD
crashes while executing FileStore::_collection_move_rename, it's
possible that the replay guard is set, but the object map map update
gets lost. When recovering, OSD checks the replay guard and does
nothing.

The fix is sync the object map in FileStore::_close_replay_guard()

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/os/filestore/DBObjectMap.cc
src/os/filestore/FileStore.cc
src/os/filestore/FileStore.h

index 67e17bdb8c89d1479867155b9934c89d2e8bb947..7e9dfe65381360e07389f620692babda1e75142a 100644 (file)
@@ -902,10 +902,10 @@ int DBObjectMap::clone(const ghobject_t &oid,
   {
     Header destination = lookup_map_header(*ltarget, target);
     if (destination) {
-      remove_map_header(*ltarget, target, destination, t);
       if (check_spos(target, destination, spos))
        return 0;
       destination->num_children--;
+      remove_map_header(*ltarget, target, destination, t);
       _clear(destination, t);
     }
   }
index 7029571212d4d95e9f47e2106d1458f38a4a06c4..68231fc65b3a8f844eb2ff6cb3c8831061696055 100644 (file)
@@ -2343,10 +2343,12 @@ void FileStore::_set_replay_guard(int fd,
   // first make sure the previous operation commits
   ::fsync(fd);
 
-  // sync object_map too.  even if this object has a header or keys,
-  // it have had them in the past and then removed them, so always
-  // sync.
-  object_map->sync(hoid, &spos);
+  if (!in_progress) {
+    // sync object_map too.  even if this object has a header or keys,
+    // it have had them in the past and then removed them, so always
+    // sync.
+    object_map->sync(hoid, &spos);
+  }
 
   _inject_failure();
 
@@ -2384,7 +2386,8 @@ void FileStore::_close_replay_guard(const coll_t& cid,
   VOID_TEMP_FAILURE_RETRY(::close(fd));
 }
 
-void FileStore::_close_replay_guard(int fd, const SequencerPosition& spos)
+void FileStore::_close_replay_guard(int fd, const SequencerPosition& spos,
+                                   const ghobject_t *hoid)
 {
   if (backend->can_checkpoint())
     return;
@@ -2393,6 +2396,11 @@ void FileStore::_close_replay_guard(int fd, const SequencerPosition& spos)
 
   _inject_failure();
 
+  // sync object_map too.  even if this object has a header or keys,
+  // it have had them in the past and then removed them, so always
+  // sync.
+  object_map->sync(hoid, &spos);
+
   // then record that we are done with this operation
   bufferlist v(40);
   ::encode(spos, v);
@@ -5158,18 +5166,30 @@ int FileStore::_collection_move_rename(const coll_t& oldcid, const ghobject_t& o
       } else {
        assert(0 == "ERROR: source must exist");
       }
-      return 0;
-    }
-    if (dstcmp > 0) {      // if dstcmp == 0 the guard already says "in-progress"
-      _set_replay_guard(**fd, spos, &o, true);
-    }
 
-    r = lfn_link(oldcid, c, oldoid, o);
-    if (replaying && !backend->can_checkpoint() &&
-       r == -EEXIST)    // crashed between link() and set_replay_guard()
-      r = 0;
+      if (!replaying) {
+       return 0;
+      }
+      if (allow_enoent && dstcmp > 0) { // if dstcmp == 0, try_rename was started.
+       return 0;
+      }
 
-    _inject_failure();
+      r = 0; // don't know if object_map was cloned
+    } else {
+      if (dstcmp > 0) { // if dstcmp == 0 the guard already says "in-progress"
+       _set_replay_guard(**fd, spos, &o, true);
+      }
+
+      r = lfn_link(oldcid, c, oldoid, o);
+      if (replaying && !backend->can_checkpoint() &&
+         r == -EEXIST)    // crashed between link() and set_replay_guard()
+       r = 0;
+
+      lfn_close(fd);
+      fd = FDRef();
+
+      _inject_failure();
+    }
 
     if (r == 0) {
       // the name changed; link the omap content
@@ -5180,9 +5200,6 @@ int FileStore::_collection_move_rename(const coll_t& oldcid, const ghobject_t& o
 
     _inject_failure();
 
-    lfn_close(fd);
-    fd = FDRef();
-
     if (r == 0)
       r = lfn_unlink(oldcid, oldoid, spos, true);
 
@@ -5191,7 +5208,7 @@ int FileStore::_collection_move_rename(const coll_t& oldcid, const ghobject_t& o
 
     // close guard on object so we don't do this again
     if (r == 0) {
-      _close_replay_guard(**fd, spos);
+      _close_replay_guard(**fd, spos, &o);
       lfn_close(fd);
     }
   }
index dca849f280131ed265fb7f1648c53d6ff6732cd0..7a9b78df923b31cd44b6604cda2bc173a63a800d 100644 (file)
@@ -497,7 +497,8 @@ public:
                                const SequencerPosition &spos);
 
   /// close a replay guard opened with in_progress=true
-  void _close_replay_guard(int fd, const SequencerPosition& spos);
+  void _close_replay_guard(int fd, const SequencerPosition& spos,
+                          const ghobject_t *oid=0);
   void _close_replay_guard(const coll_t& cid, const SequencerPosition& spos);
 
   /**