summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage.weil@dreamhost.com>2012-03-30 09:51:45 -0700
committerSage Weil <sage.weil@dreamhost.com>2012-03-30 09:52:09 -0700
commit41f84fac1ae4b4c72bf9bfe07614c4066c916fd1 (patch)
treebe3417e261d46b91543801c187fcb063460c6cb8
parentc89b7f22c8599eb974e75a2f7a5f855358199dee (diff)
downloadceph-41f84fac1ae4b4c72bf9bfe07614c4066c916fd1.tar.gz
filestore: set guard on collection_move
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>
-rw-r--r--src/os/FileStore.cc18
-rw-r--r--src/os/FileStore.h3
2 files changed, 17 insertions, 4 deletions
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc
index 2a4032a1999..f269e7bf6b5 100644
--- a/src/os/FileStore.cc
+++ b/src/os/FileStore.cc
@@ -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;
}
diff --git a/src/os/FileStore.h b/src/os/FileStore.h
index e29419af112..b13e16a99e5 100644
--- a/src/os/FileStore.h
+++ b/src/os/FileStore.h
@@ -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