diff --git a/src/os/filestore/DBObjectMap.cc b/src/os/filestore/DBObjectMap.cc index 67e17bdb8c89d..7e9dfe6538136 100644 --- a/src/os/filestore/DBObjectMap.cc +++ b/src/os/filestore/DBObjectMap.cc @@ -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); } } diff --git a/src/os/filestore/FileStore.cc b/src/os/filestore/FileStore.cc index ff92831486199..68231fc65b3a8 100644 --- a/src/os/filestore/FileStore.cc +++ b/src/os/filestore/FileStore.cc @@ -472,13 +472,7 @@ int FileStore::lfn_unlink(const coll_t& cid, const ghobject_t& o, } if (!force_clear_omap) { - if (hardlink == 0) { - if (!m_disable_wbthrottle) { - wbthrottle.clear_object(o); // should be only non-cache ref - } - fdcache.clear(o); - return 0; - } else if (hardlink == 1) { + if (hardlink == 0 || hardlink == 1) { force_clear_omap = true; } } @@ -505,6 +499,12 @@ int FileStore::lfn_unlink(const coll_t& cid, const ghobject_t& o, if (!backend->can_checkpoint()) object_map->sync(&o, &spos); } + if (hardlink == 0) { + if (!m_disable_wbthrottle) { + wbthrottle.clear_object(o); // should be only non-cache ref + } + return 0; + } } r = index->unlink(o); if (r < 0) { @@ -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); } } diff --git a/src/os/filestore/FileStore.h b/src/os/filestore/FileStore.h index dca849f280131..7a9b78df923b3 100644 --- a/src/os/filestore/FileStore.h +++ b/src/os/filestore/FileStore.h @@ -497,7 +497,8 @@ class FileStore : public JournalingObjectStore, 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); /**