diff options
author | Sage Weil <sage.weil@dreamhost.com> | 2012-03-30 09:51:45 -0700 |
---|---|---|
committer | Sage Weil <sage.weil@dreamhost.com> | 2012-03-30 09:52:09 -0700 |
commit | 41f84fac1ae4b4c72bf9bfe07614c4066c916fd1 (patch) | |
tree | be3417e261d46b91543801c187fcb063460c6cb8 | |
parent | c89b7f22c8599eb974e75a2f7a5f855358199dee (diff) | |
download | ceph-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.cc | 18 | ||||
-rw-r--r-- | src/os/FileStore.h | 3 |
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 |