diff options
author | Sage Weil <sage@redhat.com> | 2017-02-14 00:02:39 +0100 |
---|---|---|
committer | Sage Weil <sage@redhat.com> | 2017-02-14 05:03:53 +0100 |
commit | b729e6288f1e914f3fa457916493f257e82b901f (patch) | |
tree | 1c98508d789d2d35ffddd6dba43023c5555e4de3 /src/osd/Session.cc | |
parent | osd/Session: fix race between have_backoff() and clear_backoffs() (diff) | |
download | ceph-b729e6288f1e914f3fa457916493f257e82b901f.tar.xz ceph-b729e6288f1e914f3fa457916493f257e82b901f.zip |
osd: fix backoff vs reset race
In OSD::ms_handle_reset, we clear session->con before removing any
backoffs. That means we have to check if con has been cleared after any
call to have_backoff, lest we race with ms_handle_reset and it removes the
backoffs but we don't realize our client session is disconnected.
Introduce a helper to do both these checks in a safe way, simplifying
callers while we're at it.
Signed-off-by: Sage Weil <sage@redhat.com>
Diffstat (limited to 'src/osd/Session.cc')
-rw-r--r-- | src/osd/Session.cc | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/osd/Session.cc b/src/osd/Session.cc index abe1a0c9eba..2de44271344 100644 --- a/src/osd/Session.cc +++ b/src/osd/Session.cc @@ -81,3 +81,23 @@ void Session::ack_backoff( } assert(!backoff_count == backoffs.empty()); } + +bool Session::check_backoff( + CephContext *cct, spg_t pgid, const hobject_t& oid, Message *m) +{ + BackoffRef b(have_backoff(pgid, oid)); + if (b) { + dout(10) << __func__ << " session " << this << " has backoff " << *b + << " for " << *m << dendl; + assert(!b->is_acked() || !g_conf->osd_debug_crash_on_ignored_backoff); + return true; + } + // we may race with ms_handle_reset. it clears session->con before removing + // backoffs, so if we see con is cleared here we have to abort this + // request. + if (!con) { + dout(10) << __func__ << " session " << this << " disconnected" << dendl; + return true; + } + return false; +} |