]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ReplicatedPG: return error codes for dups from the pg log
authorJosh Durgin <jdurgin@redhat.com>
Wed, 11 May 2016 00:34:24 +0000 (17:34 -0700)
committerJosh Durgin <jdurgin@redhat.com>
Sat, 9 Jul 2016 01:33:13 +0000 (18:33 -0700)
This prevents reordering guarded writes or deletes.

Without this, the following sequence:

delete foo -> -ENOENT
write foo -> success
(client connection fails)
resend delete foo -> success, object deleted
resend write foo -> success - dup op, so no write performed

results in the object not existing, instead of containing data. After
this change, both delete and write are detected as dups and the
original ordering is preserved.

Fixes: http://tracker.ceph.com/issues/14468
Signed-off-by: Josh Durgin <jdurgin@redhat.com>
src/osd/PGLog.h
src/osd/ReplicatedPG.cc

index 46b2f3c4f0c132878fcf2e30205f89bd5b44e131..9df9e62f08850f0906a6e6965a6a51de8c5daa0d 100644 (file)
@@ -166,9 +166,11 @@ struct PGLog : DoutPrefixProvider {
     bool get_request(
       const osd_reqid_t &r,
       eversion_t *replay_version,
-      version_t *user_version) const {
+      version_t *user_version,
+      int *return_code) const {
       assert(replay_version);
       assert(user_version);
+      assert(return_code);
       ceph::unordered_map<osd_reqid_t,pg_log_entry_t*>::const_iterator p;
       if (!(indexed_data & PGLOG_INDEXED_CALLER_OPS)) {
         index_caller_ops();
@@ -177,6 +179,7 @@ struct PGLog : DoutPrefixProvider {
       if (p != caller_ops.end()) {
        *replay_version = p->second->version;
        *user_version = p->second->user_version;
+       *return_code = p->second->return_code;
        return true;
       }
 
@@ -194,6 +197,7 @@ struct PGLog : DoutPrefixProvider {
          if (i->first == r) {
            *replay_version = p->second->version;
            *user_version = i->second;
+           *return_code = p->second->return_code;
            return true;
          }
        }
index 993e59b9e13148cf4091045996d7ff3db4c5d54b..5e216f23a1a1d6bf3e33ed25eeb13a9c42144a49 100644 (file)
@@ -1787,13 +1787,14 @@ void ReplicatedPG::do_op(OpRequestRef& op)
     // purposes here it doesn't matter which one we get.
     eversion_t replay_version;
     version_t user_version;
+    int return_code = 0;
     bool got = pg_log.get_log().get_request(
-      m->get_reqid(), &replay_version, &user_version);
+      m->get_reqid(), &replay_version, &user_version, &return_code);
     if (got) {
       dout(3) << __func__ << " dup " << m->get_reqid()
              << " was " << replay_version << dendl;
-      if (already_complete(replay_version)) {
-       osd->reply_op_error(op, 0, replay_version, user_version);
+      if (return_code < 0 || already_complete(replay_version)) {
+       osd->reply_op_error(op, return_code, replay_version, user_version);
       } else {
        if (m->wants_ack()) {
          if (already_ack(replay_version)) {