From: Sage Weil Date: Fri, 19 Dec 2014 16:37:00 +0000 (-0800) Subject: osdc/Objecter: do notify completion callback in fast-dispatch context X-Git-Tag: v0.91~15 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5cf4483cc41904b8c08e4dc4e4cc2bba210ca184;p=ceph.git osdc/Objecter: do notify completion callback in fast-dispatch context The notify completion has exactly one user, the librados caller which does nothing but take a local (inner) lock and signal a Cond. Do this in the fast-dispatch context for simplicity. Notably, this makes the notify completion (and timeout) trigger a notify2() return (with ETIMEDOUT) even when the finisher queue that normally delivers notify is busy.. for example with a notify that is being very slow. In our case, the unit test is doing a sleep(3) to test timeouts but also prevented the ETIMEDOUT notification from being delivered to the caller. This patch resolves that. Signed-off-by: Sage Weil (cherry picked from commit 9b78dafd4a80ad9a557cfdf17d10fb2bff236f1a) --- diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 152560c5aa8..c11b0929d32 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -770,6 +770,12 @@ void Objecter::handle_watch_notify(MWatchNotify *m) if (info->watch_context) finisher->queue(new C_DoWatchError(info, -ENOTCONN)); } + } else if (!info->is_watch) { + // notify completion; we can do this inline since we know the only user + // (librados) is safe to call in fast-dispatch context + assert(info->on_notify_finish); + info->notify_result_bl->claim(m->get_data()); + info->on_notify_finish->complete(m->return_code); } else { finisher->queue(new C_DoWatchNotify(this, info, m)); } @@ -791,14 +797,6 @@ void Objecter::_do_watch_notify(LingerOp *info, MWatchNotify *m) } // notify completion? - if (!info->is_watch) { - assert(info->on_notify_finish); - info->notify_result_bl->claim(m->get_data()); - rwlock.put_read(); - info->on_notify_finish->complete(m->return_code); - goto out; - } - assert(info->is_watch); assert(info->watch_context); assert(m->opcode != CEPH_WATCH_EVENT_DISCONNECT);