]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
filestore: set guard on collection_move
authorSage Weil <sage.weil@dreamhost.com>
Fri, 30 Mar 2012 16:51:45 +0000 (09:51 -0700)
committerSage Weil <sage.weil@dreamhost.com>
Fri, 30 Mar 2012 16:52:09 +0000 (09:52 -0700)
During recovery we submit transactions like:

 - delete a/foo
 - move tmp/foo to a/foo

This prevents the EEXIST check in collection_move from doing any good,
since the destination never exists.  We need to do that remove at least
sometimes, because we may be overwriting an existing/older version of the
object.

So,
 - set the guard after we do the move, so that
 - the delete won't be repated, and
 - the EEXIST check will work

Also check the guard for good measure (although that doesn't do anything
specifically useful in this scenario).

Fixes: #2164
Signed-off-by: Sage Weil <sage@newdream.net>
Reviewed-by: Josh Durgin <josh.durgin@dreamhost.com>
Reviewed-by: Samuel Just <samuel.just@dreamhost.com>
src/os/FileStore.cc
src/os/FileStore.h

index 2a4032a199908464b2e3a4a2b1a17f900e3dac88..f269e7bf6b591761d6626eece41473354930335e 100644 (file)
@@ -2628,7 +2628,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n
        coll_t ocid = i.get_cid();
        coll_t ncid = i.get_cid();
        hobject_t oid = i.get_oid();
-       r = _collection_move(ocid, ncid, oid);
+       r = _collection_move(ocid, ncid, oid, spos);
       }
       break;
 
@@ -4271,12 +4271,24 @@ int FileStore::_collection_remove(coll_t c, const hobject_t& o)
   return r;
 }
 
-int FileStore::_collection_move(coll_t c, coll_t oldcid, const hobject_t& o) 
+int FileStore::_collection_move(coll_t c, coll_t oldcid, const hobject_t& o,
+                               const SequencerPosition& spos) 
 {
   dout(15) << "collection_move " << c << "/" << o << " from " << oldcid << "/" << o << dendl;
+
+  if (!_check_replay_guard(oldcid, o, spos))
+    return 0;
+
   int r = lfn_link(oldcid, c, o);
-  if (r == 0 || (replaying && r == -EEXIST))
+  if (r == 0 || (replaying && r == -EEXIST)) {
     r = lfn_unlink(oldcid, o);
+
+    // set guard on object so we don't do this again
+    int fd = lfn_open(c, o, 0);
+    assert(fd >= 0);
+    _set_replay_guard(fd, spos);
+    TEMP_FAILURE_RETRY(::close(fd));
+  }
   dout(10) << "collection_move " << c << "/" << o << " from " << oldcid << "/" << o << " = " << r << dendl;
   return r;
 }
index e29419af112da1341255f762a7854e6fb13e0901..b13e16a99e5d9d5f6705d27f86f1c2873da98451 100644 (file)
@@ -421,7 +421,8 @@ public:
   int _collection_add(coll_t c, coll_t ocid, const hobject_t& o,
                      const SequencerPosition& spos);
   int _collection_remove(coll_t c, const hobject_t& o);
-  int _collection_move(coll_t c, coll_t ocid, const hobject_t& o);
+  int _collection_move(coll_t c, coll_t ocid, const hobject_t& o,
+                      const SequencerPosition& spos);
 
 private:
   // omap